---
# System prepended metadata

title: NoSQL
tags: [' DB', 學習筆記]

---

---
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。
  ![](http://database.guide/wp-content/uploads/2016/06/wide_column_store_database_example_column_family-1.png)
* Graph資料庫
  * Neo4J
  * Infinite Graph
  * OrientDB
  儲存節點、關係、屬性的資料庫。
  社交網路的使用。
  ![](https://d1.awsstatic.com/product-marketing/Neptune/What-is-graph-database-social-network-diagram.a6601377b99c03ede1f2e5cf078c01467fb6890a.png)
## 為何出現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可以快速的展開工作。