系統架構設計,有了關係資料庫,為何還要採用高效能NoSQL

關係資料庫的缺點

關係資料庫經過幾十年的發展後已經非常成熟,強大的SQL功能和ACID的屬性,使得關係資料庫廣泛應用於各式各樣的系統中,但這並不意味著關係資料庫是完美的,關係資料庫存在如下缺點。

關係資料庫儲存的是行記錄,無法儲存資料結構。

關係資料庫的schema擴充套件很不方便。

關係資料庫的表結構schema是強約束,操作不存在的列會報錯,業務變化時擴充列也比較麻煩,需要執行DDL(data defnition language,如CREATE、ALTER、DROP等)語句修改,而且修改時可能會長時間鎖表(例如,MySQL可能將表鎖住1個小時)。

關係資料庫在大資料場景下I/O較高,如果對一些大量資料的表進行統計之類的運算,關係資料庫的I/O會很高,因為即使只針對其中某一列進行運算,關係資料庫也會將整行資料從儲存裝置讀入記憶體。

關係資料庫的全文搜尋功能比較弱。關係資料庫的全文搜尋只能使用like進行整表掃描匹配,效能非常低,在網際網路這種搜尋複雜的場景下無法滿足業務要求。

為何要採用NoSQL

針對上述關係資料庫存在的問題,分別誕生了不同的NoSQL解決方案,這些方案與關係資料庫相比,在某些應用場景下表現更好。但世上沒有免費的午餐,NoSQL方案帶來的優勢,本質上是犧牲ACID中的某個或者某幾個特性,

因此我們不能盲目地迷信NoSQL是銀彈,而應該將NoSQL作為SQL的一個有力補充

,NoSQL != No SQL,而是NoSQL = Not Only SQL。常見的NoSQL方案分為以下四類。

K-V儲存:解決關係資料庫無法儲存資料結構的問題,以Redis為代表。

文件資料庫:解決關係資料庫強schema約束的問題,以MongoDB為代表。

列式資料庫:解決關係資料庫大資料場景下的I/O問題,以HBase為代表。

全文搜尋引擎:解決關係資料庫的全文搜尋效能問題,以Elasticsearch為代表。

下面分別介紹一下各種

高效能NoSQL方案的典型特徵和應用場景。

一、K-V儲存

K-V儲存的全稱是Key-Value儲存,其中Key是資料的標識,和關係資料庫中的主鍵含義一樣,Value就是具體的資料。

Redis是K-V儲存的典型代表,它是一款開源(基於BSD許可)的高效能K-V快取和儲存系統。Redis的Value是具體的資料結構,包括string、hash、list、set、sorted、set、bitmap和hyperloglog,所以常常被稱為資料結構伺服器。

以List資料結構為例,Redis提供了下面這些典型的操作:

LPOP key從佇列的左邊出隊一個元素。

LINDEX key index獲取一個元素,透過其索引列表。

LLEN key獲得佇列(List)的長度。

RPOP key從佇列的右邊出隊一個元素。

以上這些功能,如果用關係資料庫來實現,就會變得很複雜並且效能很低。

Redis的缺點主要體現在並不支援完整的ACID事務,Redis雖然提供事務功能,但Redis的事務和關係資料庫的事務不可同日而語,Redis的事務只能保證隔離性和一致性(I和C),無法保證原子性和永續性(A和D)。

雖然Redis並沒有嚴格遵循ACID原則,但實際上大部分業務也不需要嚴格遵循ACID原則。以上面的微博關注操作為例,即使系統沒有將A加入B的粉絲列表,其實業務影響也非常

小,因此我們在設計方案時,需要根據業務特性和要求來確定是否可以用Redis,而不能因為Redis不遵循ACID原則就直接放棄。

二、文件資料庫

為了解決關係資料庫schema帶來的問題,文件資料庫應運而生。文件資料庫最大的特點就是no-schema,可以儲存和讀取任意的資料。目前絕大部分文件資料庫儲存的資料格式

是JSON(或者BSON),因為JSON資料是自描述的,無須在使用前定義欄位,讀取一個JSON中不存在的欄位也不會導致SQL那樣的語法錯誤。

文件資料庫的no-schema特性,給業務開發帶來了幾個明顯的優勢。

1。新增欄位簡單

業務上增加新的欄位,無須再像關係資料庫一樣要先執行DDL語句修改表結構,程式程式碼直接讀寫即可。

2。歷史資料不會出錯

對於歷史資料,即使沒有新增的欄位,也不會導致錯誤,只會返回空值,此時程式碼進行相容處理即可。

3。可以很容易儲存複雜資料

JSON是一種強大的描述語言,能夠描述複雜的資料結構,使用JSON來描述資料,比使用關係型資料庫表來描述資料方便和容易得多,而且更加容易理解。

三、列式資料庫

顧名思義,列式資料庫就是按照列來儲存資料的資料庫,與之對應的傳統關係資料庫被稱為“行式資料庫”,因為關係資料庫是按照行來儲存資料的。

關係資料庫按照行式來儲存資料,主要有以下幾個優勢:

業務同時讀取多個列時效率高,因為這些列都是按行儲存在一起的,一次磁碟操作就能夠把一行資料中的各個列都讀取到記憶體中。

能夠一次性完成對一行中的多個列的寫操作,保證了針對行資料寫操作的原子性和一致性;否則如果採用列儲存,可能會出現某次寫操作,有的列成功了,有的列失敗了,導致資料不一致。

除了節省I/O,列式儲存還具備更高的儲存壓縮比,能夠節省更多的儲存空間。普通的行式資料庫一般壓縮率在3:1到5:1左右,而列式資料庫的壓縮率一般在8:1到30:1左右,因為單個列的資料相似度相比行來說更高,能夠達到更高的壓縮率。

同樣,如果場景發生變化,列式儲存的優勢又會變成劣勢。典型的場景是需要頻繁地更新多個列。因為列式儲存將不同列儲存在磁碟上不連續的空間,導致更新多個列時磁碟是隨機寫操作;而行式儲存時同一行多個列都儲存在連續的空間,一次磁碟寫操作就可以完成,列式儲存的隨機寫效率要遠遠低於行式儲存的寫效率。此外,列式儲存高壓縮率在更新場景下也會成為劣勢,因為更新時需要將儲存資料解壓後更新,然後再壓縮,最後寫入磁碟。

基於上述列式儲存的優缺點,一般將列式儲存應用在離線的大資料分析和統計場景中,因為這種場景主要是針對部分列單列進行操作,且資料寫入後就無須再更新刪除。

四、全文搜尋引擎

傳統的關係型資料庫透過索引來達到快速查詢的目的,但是在全文搜尋的業務場景下,索引也無能為力,主要體現在:

全文搜尋的條件可以隨意排列組合,如果透過索引來滿足,則索引的數量會非常多。

全文搜尋的模糊匹配方式,索引無法滿足,只能用like查詢,而like查詢是整表掃描,效率非常低。全文搜尋引擎彌補了關係資料庫在支撐全文搜尋時的不足,特點如下:

1。全文搜尋基本原理

全文搜尋引擎的技術原理被稱為“倒排索引”(Inverted index),也常被稱為反向索引、置入檔案或反向檔案,是一種索引方法,其基本原理是建立單詞到文件的索引。之所以被稱為“倒排”索引,是和“正排“索引相對的,“正排索引”的基本原理是建立文件到單詞的索引。我們透過一個簡單的樣例來說明這兩種索引的差異。

2。全文搜尋的使用方式

全文搜尋引擎的索引物件是單詞和文件,而關係資料庫的索引物件是鍵和行,兩者的術語差異很大,不能簡單地等同起來。因此,為了讓全文搜尋引擎支援關係型資料的全文搜尋,需要做一些轉換操作,即將關係型資料轉換為文件資料。

Elastcisearch是分散式的文件儲存方式。它能儲存和檢索複雜的資料結構——序列化成為JSON文件——以實時的方式。在Elasticsearch中,每個欄位的所有資料都是預設被索引的。即每個欄位都有為了快速檢索而設定的專用倒排索引。而且,不像其他大多數的資料庫,它能在相同的查詢中使用所有倒排索引,並以驚人的速度返回結果。

好了,以上就是高效能架構設計方案中,為何要採用NoSQL,希望對你有所幫助。