SQL or NoSQL?

SQL or NoSQL?

寫在前面
對於關係型數據庫,(必要時)咱們能夠經過反範式化犧牲一部分寫入性能,來換取更高的讀取性能,但前提是先要知足範式設計,接着在此基礎上進行局部調整,故意打破一些規則數據庫

與其先範式化,遭遇性能瓶頸再進行反範式化,不如從一開始就考慮反範式設計——直接採用 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 數據庫支持一些更靈活的數據結構,使得某些操做更快

鍵值存儲
SQL or 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):

SQL or NoSQL?

僅含列的行稱爲列族(column family),含有超級列的行稱爲超級列族(super column family),每一行(即,一個列族或超級列族)表明一個實體,包含該實體的全部相關信息:

SQL or NoSQL?

數據模型上是個二維 Map,特色是高性能以及良好的擴展性,所以適用於很是大的數據集,被 Twitter、Facebook 等社交網絡用來存儲海量用戶所產生的數據

P.S.例如 Google 最先推出的Bigtable、Hadoop 生態中的HBase,以及 Facebook 推出的Cassandra

圖形數據庫

SQL or NoSQL?
數據基於圖來建模,圖中每一個節點表明一條記錄,每條邊表示節點之間的關係,所以可以輕鬆描述數據對象之間的複雜關係,好比關係模型中複雜的外鍵和多對多關係

圖形數據庫的實際應用還不十分紅熟,甚至尚未一種被普遍採用的標準化查詢語言,但其鏈接性優點尤爲適用於具備複雜關係的數據模型(好比社交網絡),值得期待:

SQL or NoSQL?

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

相關文章
相關標籤/搜索