迷失在NoSQL的叢林中了?你需要這份導游手冊
Nosql數據庫
NoSQL這個詞,意思是 "不僅僅是SQL",最早出現在20世紀90年代末,指的是為了解決網絡和云數據管理的要求,克服傳統SQL技術的限制而建立的新系統(見我們的 blog post on SQL vs. NoSQL vs NewSQL不同方法之間的比較)。這些限制是缺乏橫向可擴展性,數據攝取效率低,模式僵化,以及難以支持復雜的數據,如文檔和圖表。
圖1:傳統的SQL數據庫
作為支持標準關系模型的傳統SQL數據庫的替代品,NoSQL系統支持標準SQL以外的數據模型和查詢語言。它們通常強調可擴展性(以犧牲一致性為代價)、靈活的模式和實用的API,用于編程復雜的數據密集型應用。為了提供可擴展性,NoSQL系統通常在一個無共享的集群中使用擴展的方法(見 blog post on shared-nothing),并進行復制以保證可用性。
大數據軟件棧中的nosql
根據底層數據模型,NoSQL系統有四大類(?zsu & Valduriez, 2020),例如,鍵值數據存儲、寬列存儲、文檔存儲和圖形數據庫。在每個類別中,我們可以找到數據模型的不同變化(與標準化的關系數據模型不同)和不同的查詢語言或API。然而,對于文檔存儲,JSON正在成為事實上的標準。還有一些多模型數據存儲,在一個系統中結合了多種數據模型,通常是文檔和圖形。
圖2:NoSQL類別
鍵值數據存儲和寬列存儲
鍵值數據存儲和寬列存儲有時被歸為同一類,因為它們都是無模式的,并且共享許多特征。在鍵值數據模型中,所有的數據都被表示為鍵值對,其中鍵是唯一的標識值。鍵值系統是無模式的,這產生了巨大的靈活性和可擴展性。它們通常提供一個簡單的接口,如put(key,value),value=get(key),and delete(key)。寬列存儲可以將行存儲為屬性-值對的列表。第一個屬性被稱為主鍵或主鍵,例如,社會安全號碼,它在一個行的集合中唯一地識別一個行,例如,人。鍵通常是排序的,這使得范圍查詢和鍵的有序處理成為可能。這是寬列存儲的一種能力,鍵值存儲通常不支持。
鍵值數據存儲有一個分布式的架構,在一個無共享的集群中可以線性擴展。一個鍵值集合的行通常是水平分區的,使用散列或鍵值范圍,并存儲在一些集群節點上。鍵值數據存儲也善于使用SSTables有效地攝取數據(他們聲稱使用LSM樹,但實際上使用SSTables,見我們的 blog post on B+ Trees, LSM trees and SSTables),這是一種數據結構和攝取算法,通過使用單個I/O來插入許多行,在攝取數據方面非常高效。鍵值數據存儲解決了僵化的模式問題,僅僅是通過無模式,每一行都可以有不同的結構,即任意的列集。
圖3:B+樹和SST表的比較
鍵值數據存儲的這些新特性影響了性能。首先,SST表格在查詢數據方面的效率很低,所以在鍵值數據存儲中讀取數據的成本要比使用B+樹的SQL數據庫高很多。其次,模式的靈活性意味著數據表示在空間方面變得更加昂貴,因為列名必須被編碼并存儲在行內。更重要的是,一般用于打包相同大小的列的技術不能被應用,所以數據表示的效率更低。由于其固定的模式,SQL數據庫可以在行中組織列,在空間和訪問時間方面非常有效。
圖4:關系型和無模式型方法的比較
最后,鍵值存儲以強大的數據一致性換取可擴展性和可用性,依賴于不同的控制一致性的方式,如副本的最終一致性,有條件的寫入,以及最終一致性和強一致性的讀取。
圖5:鍵值數據存儲的屬性
寬列存儲結合了SQL數據庫的一些有益特性(例如,以表的形式表示數據)和鍵值存儲的靈活性(例如,列內無模式數據)和可擴展性。寬列表中的每一行都由一個鍵唯一標識,并有一些命名的列。然而,與關系表不同的是,列只能包含原子值(即二進制字符串),一個列可以很寬,包含多個鍵值對。寬列存儲用更多的聲明性結構擴展了鍵值存儲接口,允許對列族進行掃描、精確匹配和范圍查詢。它們通常為這些結構提供一個API,以便在編程語言中使用。
圖6:鍵值和寬列存儲的比較