RDBMS#
Relational Database Management System
- 在資料之間有很強的 Relation(關聯性) 的時候使用:
- 設計不太會去變動的 schema 將 table 互相關聯, 就可以透過 SQL 取得想要的資料。
- 資料的正確性很重要的時候使用:
- 通常會提供ACID。
- 要變動 schema 是一件很浩大的工程:
- 要把 table 的 schema 更新還要 migrate 資料。
- 所有用到要被更換 schema 的 table 的程式都要修改。
- 可以對不同的 table 執行
join操作。
- Vertical scaling(垂直擴展) 效果比較明顯(提升機器的性能)。
- 在分散式資料切片上透過網路執行
join,會帶來巨大的延遲瓶頸與網路開銷。
- 在分散式資料切片上透過網路執行
ACID#
通常 RDBMS 會保證交易(transaction)有四種特性:
Atomicity 只有 全部做完(Commit) 跟 全部沒做(Abort) 兩種可能, 沒有做了一半這種狀態。 如果執行中有 error 的話就會 Rollback 成全部沒做的狀態。
Consistency 交易前後 database 都會保持合法的狀態。
Isolation 多筆 transaction 都要執行時,每筆 transaction 都是分開的,不會互相干擾。 A 和 B 做交易不影響 B 和 C 做交易。
Durability Transaction 做完了就是永久有效的,不會失效, 就算系統突然壞了也一樣。
NoSQL#
Not only SQL
- 比較不在意資料之間的 Relation:
- 存取資料時不需要固定的 schema。
- 每筆資料單獨存在,沒有誰關聯誰的問題。
- 比較在意資料的內容,可以分為四種類型:
- Key-value 儲存
- Graph 儲存
- Column 儲存
- Document 儲存
- NoSQL 通常不支援
join操作。 - Horizontal scaling(水平擴展、Sharding) 效果比較明顯(多找幾台機器)。
- 對於 NoSQL 資料庫叢集,通常提供 CAP 其中兩種特性。
- 水平擴展對大規模應用更理想,因為它提供故障轉移(failover)與冗餘(redundancy)。
CAP Theorem#
對一個分散式系統來說, CAP 三種特性不可能都能保證同時存在(但有可能同時存在,例如網路很順的時候), 頂多同時能保證存在兩種。
Consistency 每次 read 如果不是得到 error,都會讀到最近一次寫入的結果。 => 每個 node 的 data 都是一樣的。
Availability 每個 request 都會得到一個不是 error 的 response, 不管這個 response 回傳的資料是不是最新的。 => 怎麼樣都保證資料會被回傳,不過資料可能是舊的。
Partition tolerance 就算有些在 node 之間傳送的訊息被 delay 或是掉了,系統也會繼續運作。 => 網路有狀況的時候,正常連線的那一部份 node 可以正常運行。
如何選擇#
NoSQL#
- 低延遲需求
- 非結構化資料,或沒有關聯性的資料
- 只需要序列化與反序列化資料(JSON、XML、YAML 等)
- 需要儲存大量資料
Scaling#
Vertical Scaling(垂直擴展)#
增加機器的 CPU、RAM、磁碟空間。
- 有 SPOF(Single Point Of Failure,單點故障) 的風險。
Horizontal Scaling(水平擴展、Sharding)#
增加更多伺服器,每個 shard 儲存相同 schema 下不同的唯一資料。
- Sharding key(partition key) 與 sharding function 用來決定資料應存在哪個 shard,可以是資料的一欄或多欄。
挑戰:
- Shard 耗盡:sharding function 需要更新,資料也需要搬移。
- Celebrity 問題(熱點問題)
- 無法跨 shard 執行
join:需要進行反正規化(denormalization)。
