---
tags: 學習筆記, DB
---
NoSQL
===
## NoSQL的概念
NoSQL(non SQL or non relational)最初泛指所有非傳統關聯式資料庫的資料庫管理系統,後來有人提出了Not only SQL的概念,指出混用關聯式資料庫與NoSQL來達成更好的效果。
### SQL
結構化查詢語言,專門用來操作關聯式資料庫系統(MySQL、SQL Server、Oracle)進行CRUD(新增、查詢、修改、刪除)的語言。
資料正規化、遵從ACID。
* Atomicity: 單獨性
* Consistency: 一致性
* Isolation: 隔離性
* Durability: 持久性
### NoSQL
不同於SQL統一的標準,NoSQL有許多不同專長的資料庫,遵從CAP定理。
* **Consistency: 一致性** (所有節點在同一時間具有相同的數據)
* **Availability: 可用性** (保證每個請求不管成功或者失敗都有響應)
* **Partition tolerance: 分隔容忍** (系統中任意信息的丟失或失敗不會影響系統的繼續運作)
分布式系統只能滿足其二,而必須有所取捨。
* 滿足一致性,分區容忍性的系統,通常性能不是特別高:
* BigTable (column-oriented/tabular)
* Hypertable (column-oriented/tabular)
* HBase (column-oriented/tabular)
* MongoDB (document-oriented)
* Terrastore (document-oriented)
* Redis (key-value)
* Scalaris (key-value)
* MemcacheDB (key-value)
* Berkeley DB (key-value)
* 滿足可用性,分區容忍性的系統,通常可能對一致性要求低一些:
* Dynamo (key-value)
* Voldemort (key-value)
* Tokyo Cabinet (key-value)
* KAI (key-value)
* Cassandra (column-oriented/tabular)
* CouchDB (document-oriented)
* SimpleDB (document-oriented)
* Riak (document-oriented)
### NoSQL的分類
* Key-Value資料庫
* Riak
* Redis
使用鍵值儲存資料,有不錯的性能及擴展性。適合帳號資料、對話、參數、購物車等的儲存方式,不支援交易、關聯、無法透過值來查詢資料。
* Document資料庫
* MongoDB
* CouchDB
* RavenDB
以document為最小單位的儲存,每個文檔內部以XML、JSON等形式儲存資料。
沒有固定的欄位限制適合文件日誌的儲存。不支援交易、關聯。
```JSON
[{
"_id": "10280",
"city": "NEW YORK",
"state": "NY",
"pop": 5574,
"loc": [-74.016323, 40.710537]
}, {
"_id": "10281",
"city": "NEW YORK",
"state": "NY",
"pop": 5575
}]
```
* Wide Column Store資料庫
* Cassandra
* HBase
透過欄來儲存資料。
`map<key1, map<key2,value>>`
通常會將經常被一起查詢的相關資料放在同一個column family。

* Graph資料庫
* Neo4J
* Infinite Graph
* OrientDB
儲存節點、關係、屬性的資料庫。
社交網路的使用。

## 為何出現NoSQL
傳統SQL資料庫提供了良好的控制方法、統一的標準、使用三四十年的可靠性。
然而隨著時代的發展,關聯資料庫漸漸的產生瓶頸。
隨著網路的發達,Web2.0時代使用者不斷增長,大數據時代下,傳統資料庫漸漸無法負荷不斷成長的讀寫需求、多使用者導致的負載無法有效擴展升級(只能縱向成長無法橫向擴展)、不斷變動的資料需求。
同時,對於大多數Web2.0的應用我們不見得需要SQL提供的ACID與交易保證,因此發展出具備:
* 易擴展
* 靈活的資料結構
* 高可用性
* 高性能(無關聯性資料)
等特性的NoSQL。
### 易擴展
傳統資料庫隨著資料量的提升效能會產生瓶頸,解決方法無外乎買更強大、更快速的伺服器進行升級,或是透過複雜的辦法將資料進行分區分片。
而NoSQL基本上都可透過橫向擴展的方式,透過分散式結構的設計不斷購置新的主機以提升效能。
由於分散式設計,資料會被分散複製到不同節點中,每個節點各自都能異動資料再彼此同步。同步過程就會產生時間差,資料就有可能不一致。
為了保持分散式結構,NoSQL允許這樣的情況只保證最終一致性,而在資料尚未同步的期間由開發者自行解決資料衝突或遺失的問題。
### 靈活的結構
關聯式資料庫由於嚴格的關聯制定,導致資料的結構更動是複雜而困難的,而NoSQL由於無須定義欄位、資料間的關聯,可以快速的適應新的資料結構,也可以很有效的儲存半結構化或非結構化的資料。
### 高可用性、高性能
由於資料庫的結構簡單因此可以應付大量的讀寫,並具備相當優秀的效能。
### SQL VS NoSQL
||關聯式資料庫|非關聯式資料庫|原因|
|:---:|:---:|:---:|:---:|
|讀寫速度|慢|快速|資料量巨大時,關聯式資料庫邏輯複雜,資料讀寫速度下滑嚴重。NoSQL多數儲存邏輯單純,部份資料直接放在記憶體上進一步提升讀寫速度。|
|儲存容量|有限|支援巨量資料的存取與流量需求|由於關聯性的存在,要從大量關聯性中搜尋資料變得困難。|
|關聯性|一致|X||
|更新開銷|小|大|資料經過正規化,因此更新的開銷較小。|
|Join|O|X||
|擴充性|縱向擴展|橫向擴展|由於資料表之間的關聯,無法簡單的採用分散式設計,要提升效能只能不斷加強單一主機。|
|成本|高|低|NoSQL大多數都是開源軟體,沒有License成本。|
## SQL與NoSQL的抉擇
### SQL的優勢
傳統並非全然是貶意,SQL經歷時間的考驗仍然具有十足強大的功能,除此之外,SQL具有統一的標準,更換不同SQL資料庫是簡單的。而長期的使用下來SQL可以說是多數人最為熟悉的資料庫系統,在技術上我們有大量的資料可以幫助我們解決問題。
SQL具有ACID、交易的特性,可以讓我們更放心的儲存特定資料,完成特定功能開發。
嚴格的欄位與關聯性制定,可以保證我們不會儲存錯誤的資料。
在小型系統上SQL足以滿足我們所需,也幫助我們節省開發成本。
### 總結
* SQL:資料完整性必須、可以被預先確定的邏輯相關資料
* NoSQL:非關係型、模糊或不斷演進的資料儲存、需要速度和可擴展性、簡單寬鬆的目標採用NoSQL可以快速的展開工作。