寫在前面
對於關係型數據庫,(必要時)咱們能夠經過反範式化犧牲一部分寫入性能,來換取更高的讀取性能,但前提是先要知足範式設計,接着在此基礎上進行局部調整,故意打破一些規則數據庫
與其先範式化,遭遇性能瓶頸再進行反範式化,不如從一開始就考慮反範式設計——直接採用 NoSQL緩存
一.什麼是 NoSQL?
不一樣於關係型數據庫,NoSQL 數據庫(也叫非 SQL 或非關係型數據庫)提供的數據存儲、檢索機制並非基於表關係建模的:網絡
A NoSQL (originally referring to 「non SQL」 or 「non relational」) database provides a mechanism for storage and retrieval of data that is modeled in means other than the tabular relations used in relational databases.
沒有了數據表,天然就沒有了多表連查(join操做)的性能顧慮,範式約束和反範式化的抉擇也就不復存在了數據結構
但是,沒有了數據表,數據該如何組織,關係要怎樣描述呢?併發
實際上,SQL(關係型數據庫)並非惟一的選擇app
Not Only SQL
對於 NOSQL,另外一種有趣的理解是 Not Only SQL,在關係型數據庫以外的廣闊世界裏,數據不必定非要打平存放到二維表格裏,關係也不是隻能用主鍵、外鍵、關係表來描述分佈式
就數據庫類型而言,NoSQL 指的是除關係型之外的其它類型的數據庫,即非關係型數據庫(NoREL, Non Relational),例如MongoDB、CouchDB等ide
從使用角度來看,踐行 NoSQL 並不必定先要選個 NoSQL 數據庫,以「NoSQL」的方式來使用 MySQL 等關係型數據庫固然也算:工具
You can stay with MySQL, and use it like a NoSQL database.oop
好比在數據表中存一列 JSON 字符串,把這一列看成鍵值數據庫來用
二.4 種 NoSQL 數據庫
不一樣於關係型數據庫中的表結構,NoSQL 數據庫支持一些更靈活的數據結構,使得某些操做更快
鍵值存儲
鍵值存儲(Key-value store)是最簡單的 NoSQL 數據模型,只能存鍵值對兒,只能按 key 查詢,由於所存儲的值對數據庫系統不透明(相似於 BLOB),沒法根據值的特徵查找或創建索引
P.S.有些鍵值數據庫可以對 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 等社交網絡用來存儲海量用戶所產生的數據
P.S.例如 Google 最先推出的Bigtable、Hadoop 生態中的HBase,以及 Facebook 推出的Cassandra
圖形數據庫
數據基於圖來建模,圖中每一個節點表明一條記錄,每條邊表示節點之間的關係,所以可以輕鬆描述數據對象之間的複雜關係,好比關係模型中複雜的外鍵和多對多關係
圖形數據庫的實際應用還不十分紅熟,甚至尚未一種被普遍採用的標準化查詢語言,但其鏈接性優點尤爲適用於具備複雜關係的數據模型(好比社交網絡),值得期待:
P.S.例如Neo4j、Oracle Spatial and Graph、ArangoDB等
三.NoSQL 意味着什麼?
採用簡單的 NoSQL 模型(如鍵值存儲),至關於把一部分工做從數據庫層轉移到了應用層:
Joins will now need to be done in your application code.
與數據庫層相比,應用層一般更容易(橫向)擴展,所以這種工做量轉移有助於提高系統的可擴展性,將複雜的數據操做拋給應用層來處理,以求更大的優化空間
甚至事務等強一致性保證也要由應用層來處理,由於多數 NoSQL 數據庫並不提供事務支持:
Most NoSQL stores lack true ACID transactions, although a few databases have made them central to their designs.
ACID vs. BASE
不一樣於關係型數據庫中追求的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)
只支持存取結構化數據,關係模式(如表結構)必須預先定義,而且修改爲本高
P.S.關於 Object-relational impedance mismatch 的更多信息,見Why is MongoDB wildly popular? It’s a data structure thing.
而 NoSQL 數據庫(非關係型數據庫)的優點集中在:
不存在複雜的連表查詢
容易擴展(一些 NoSQL 數據庫支持自動分片)
與 OOP 數據模型一致,易於使用
沒必要預先定義數據模式,支持存取快速變化的結構化、半結構化和非結構化數據
讀寫性能(IOPS)很高,適合數據密集型工做
主要缺陷在於:
缺乏強一致性保證
開發人員、社區、工具等沒那麼成熟
應用場景
所以,NoSQL 數據庫適用於:
快速變化數據,如點擊流(click stream)數據或日誌數據
排行榜或評分數據
臨時數據,如購物車數據
頻繁訪問的熱點數據
元數據(metadata),以及查找表(lookup tables)
參考資料
Scalability for Dummies – Part 2: Database
Why is MongoDB wildly popular? It’s a data structure thing.
SQL & NOSQL: A BRIEF HISTORY
Graph Databases for Beginners: A (Brief) Tour of Aggregate Stores