文章目錄
- NoSQL定義
- NoSQL種類
- 鍵值存儲
- 文檔存儲
- 寬列存儲
- 圖形數據庫
- NoSQL 意味著什么
- ACID vs. BASE
- SQL or NoSQL
NoSQL定義
不同于關系型數據庫,NoSQL 數據庫(也叫非 SQL 或非關系型數據庫)提供的數據存儲、檢索機制并不是基于表關系建模的。沒有了數據表,自然就沒有了多表連查(join操作)的性能顧慮,范式約束和反范式化的抉擇也就不復存在了。
對于 NOSQL,另一種有趣的理解是 Not Only SQL,在關系型數據庫之外的廣闊世界里,數據不一定非要打平存放到二維表格里,關系也不是只能用主鍵、外鍵、關系表來描述。
NoSQL種類
不同于關系型數據庫中的表結構,NoSQL 數據庫支持一些更靈活的數據結構,使得某些操作更快。
鍵值存儲
鍵值存儲(Key-value store)是最簡單的 NoSQL 數據模型,只能存鍵值對兒,只能按 key 查詢,因為所存儲的值對數據庫系統不透明(類似于 BLOB),無法根據值的特征查找或建立索引。
有些鍵值數據庫能夠對 key 進行排序,從而支持范圍查詢(檢索 key 在特定區間內的數據),比如找出工號大于 100000 的新人信息。
數據模型上是個哈希表,因此能夠達到O(1)的讀寫性能,適用于簡單、或者頻繁更改的數據,經常用作內存緩存,例如Memcached
、Redis
。
文檔存儲
文檔存儲(Document store)以文檔(XML、JSON 等半結構化數據)為中心建模,相當于增強版的鍵值存儲,面向文檔提供更精細的數據操作。與鍵值存儲最大的區別在于數據庫能夠理解并處理所存儲的值(即文檔),根據值的特征(即文檔的內部結構)查詢和建立索引。此外,文檔還支持嵌套,甚至MongoDB
、CouchDB
等文檔數據庫還提供了類 SQL 的查詢語言,以支持復雜查詢。適用于持久化存儲,用來存放不經常更改的數據,作為關系型數據庫的一般替代方案。
寬列存儲
寬列存儲(Wide column store)中,列(column)是最小的數據單元,每一列是個名值對兒(以及用于版本控制和沖突解決的時間戳),在列之上還有一級超級列(super column):
僅含列的行稱為列族(column family),含有超級列的行稱為超級列族(super column family),每一行(即,一個列族或超級列族)代表一個實體,包含該實體的所有相關信息:
數據模型上是個二維 Map,特點是高性能以及良好的擴展性,因此適用于非常大的數據集,被 Twitter、Facebook 等社交網絡用來存儲海量用戶所產生的數據。
圖形數據庫
數據基于圖來建模,圖中每個節點代表一條記錄,每條邊表示節點之間的關系,因此能夠輕松描述數據對象之間的復雜關系,比如關系模型中復雜的外鍵和多對多關系
圖形數據庫的實際應用還不十分成熟,甚至還沒有一種被廣泛采用的標準化查詢語言,但其連接性優勢尤其適用于具有復雜關系的數據模型(比如社交網絡),值得期待。
NoSQL 意味著什么
采用簡單的 NoSQL 模型(如鍵值存儲),相當于把一部分工作從數據庫層轉移到了應用層。與數據庫層相比,應用層通常更容易(橫向)擴展,因此這種工作量轉移有助于提升系統的可擴展性,將復雜的數據操作拋給應用層來處理,以求更大的優化空間。
甚至事務等強一致性保證也要由應用層來處理,因為多數 NoSQL 數據庫并不提供事務支持。
ACID vs. BASE
關于這兩者的定義解釋可以看看我以前的文章:
BASE理論(基本可用策略+ 最終一致性實現) 和 什么是ACID理論(二階段、三階段提交、TCC)
不同于關系型數據庫中追求的ACID(事務的 4 大特性):
- Atomicity(原子性):一系列操作要么全部成功要么失敗全部回滾
- Consistency(一致性):事務執行前后數據庫都必須處于一致性狀態(滿足既定的所有一致性約束)
- Isolation(隔離性):并發事務操作的結果狀態與按順序執行一樣
- Durability(持久性):事務一旦提交,對數據的改變就是永久性的,遭遇故障也不會丟失已提交的結果
NoSQL 在CAP 的抉擇中對 C 做了妥協,允許最終一致性,即BASE:
- Basically Available(基本可用):讀寫操作盡可能保證可用,但不保證任何一致性
- Soft state(軟狀態):由于沒有一致性保證,在一段時間后,只是有可能讀到最新狀態,因為可能還沒收斂
- Eventual consistency(最終一致性):如果系統運行正常,等待足夠長的時間后,最終能夠讀到最新狀態
也就是說,在分布式環境下,(大多數)NoSQL 數據庫僅保證最終一致性,可能無法立即讀到最新的數據。
SQL or NoSQL
相比之下,SQL 數據庫(關系型數據庫)的優勢在于:
- 支持事務操作
- 有明確的擴展模式
- 開發人員、社區、工具等相對成熟
主要缺陷是:
- 復雜的連表查詢導致數據讀取性能不佳
- 不太容易擴展(手動分片)
- 關系模型與 OOP 之間存在較大差異(Object-relational impedance mismatch)
- 只支持存取結構化數據,關系模式(如表結構)必須預先定義,并且修改成本高
而 NoSQL 數據庫(非關系型數據庫)的優勢集中在:
- 不存在復雜的連表查詢
- 容易擴展(一些 NoSQL 數據庫支持自動分片)
- 與 OOP 數據模型一致,易于使用
- 不必預先定義數據模式,支持存取快速變化的結構化、半結構化和非結構化數據
- 讀寫性能(IOPS)很高,適合數據密集型工作
主要缺陷在于:
- 缺少強一致性保證
- 開發人員、社區、工具等沒那么成熟
因此,NoSQL 數據庫適用于:
- 快速變化數據,如點擊流(click stream)數據或日志數據
- 排行榜或評分數據
- 臨時數據,如購物車數據
- 頻繁訪問的熱點數據
- 元數據(metadata),以及查找表(lookup tables)