SQL / NoSQL,ACID與BASE一致性模型以及CAP定理的高級概述

> Photo by fabio on Unsplash
內容概述
· SQL與NoSQL數據庫概述
· ACID與BASE一致性模型
· CAP定理
· NoSQL的優勢與劣勢
SQL數據庫
SQL代表結構化查詢語言。 人們提到SQL數據庫時,實際上是在指關系數據庫管理系統(RDBMS)。
數據以表格形式存儲。 每行由主鍵唯一標識,并且每行還可以具有外鍵,該外鍵是另一個表的主鍵。 通過外鍵,與另一個表形成了一個關系-因此關系數據庫的概念。
SQL數據庫的示例包括MySQL,PostgreSQL和Oracle數據庫。

> Relationship between Student and Department Tables
NoSQL數據庫
NoSQL被稱為"無SQL",有時也稱為"不僅SQL"。 當數據庫可以支持SQL類型查詢時,使用后一個術語。
NoSQL數據庫有四種類型:
· 文件(例如Firestore)。
· 圖(例如Neo4j)。
· 鍵值(例如Riak,Berkeley DB)。
· 寬列(例如Cassandra,HBase)。
四種類型的數據庫支持不同的數據存儲方式,而不是將數據存儲在SQL數據庫的表中。
考慮NoSQL的一種簡化方法是想象一個JSON結構。 您需要一個鍵才能檢索值。

> JSON schematic representation of a NoSQL database
現在,您已經對這兩種類型的數據庫有了全面的了解,讓我們看一下一致性模型,這將有助于我們了解這兩種數據庫之間的權衡。
SQL數據庫的ACID模型
原子性
當一個事務(讀/寫)發生時,它應該一次全部發生,或者根本不發生。 如果事務中止,則數據庫不會受到影響。 同樣,如果交易通過,數據庫的狀態應反映出更改。 本質上,它全有還是全無。
一致性
事務完成后,數據庫實例(例如副本)應同時反映相同的狀態。
隔離
每個事務應獨立執行。 這意味著沒有兩個事務會引起競爭條件。 數據庫在該行上設置了鎖,以確保事務按順序發生。
耐用性
提交事務后,即使系統崩潰,修改也將是永久的。
ACID屬性可確保在交易完成后,整個數據都是一致的。 但是,這是以鎖定數據庫為代價的。
NoSQL數據庫的基礎模型
NoSQL數據庫在設計時考慮了規模,因此遵循BASE屬性而不是ACID。
基本可用性
數據庫傾向于數據的可用性,而不是數據的正確性。
軟態
數據庫存儲(例如副本)不必始終保持一致。
最終一致性
一段時間后,數據庫存儲最終將相互一致。
NoSQL數據庫面向可伸縮性,因此具有更高的容錯能力。 換句話說,當副本崩潰時,NoSQL數據庫仍然可以返回數據,盡管不是最準確的版本。
CAP定理
擁有這兩個一致性模型使我們可以很好地選擇CAP定理,該定理指出:
分布式數據庫系統只能具有3:一致性,可用性和分區容忍中的2個。

> CAP Theorem Diagram
耐分區
在討論ACID與BASE時,我們已經討論了一致性和可用性。 我們還知道,SQL數據庫更注重一致性,而NoSQL數據庫則面向可用性。 那么,分區容忍度是什么?
假設在集群中,在主-主設置中有兩個節點X和Y。 當我們將請求指向這些節點時,X和Y之間的連接斷開,因此我們遇到了一個問題:X和Y上的數據不一定同步,并且我們不知道哪個節點具有正確的數據。 節點應如何響應請求?
· 給予回應。 優先考慮可用性,但犧牲一致性(AP),因為數據可能不一定準確。
· 不要回應。 一致性被優先考慮,因為如果數據不準確,節點將不響應,但是在過程(CP)中會犧牲可用性。
第三個組合是CA,它尊重一致性和可用性,但不能存在分區(節點之間的故障)。
NoSQL的優勢
1.更快的插入/檢索
規范化是將數據隔離到單獨的表中以減少冗余和重復數據的過程。 SQL數據庫通常采用此范例。 在前面的示例中,我們看到Student表引用了Department表中一行的ID。 如果部門的位置發生變化,我們可以簡單地對Department表進行修改,而不會影響Student表。
相反,NoSQL數據庫通常支持非規范化,其中可以在記錄之間復制數據。 我們看到部門數據實際上是在所有記錄中復制的。 由于學生和部門的數據包含在一條記錄中,因此檢索速度更快,因為不需要表聯接(可能在SQL數據庫中是必需的)。
另外,由于所有數據都存儲在單個記錄中,因此可以通過一次調用NoSQL數據庫來完成插入數據庫的操作,而不必進行多次調用來用SQL數據庫更新不同的表。
2.靈活的模式
向SQL數據庫中的表添加新屬性是一項昂貴的操作。 需要將新列添加到每一行,并且為了保持一致性(副本之間),在添加新列時需要對存儲進行鎖定。
另一方面,NoSQL數據庫不需要嚴格的架構,每個記錄可以具有所需的任何鍵/值對。
3.專為可擴展性而設計
SQL數據庫的設計不能很好地橫向擴展。 盡管可以進行水平分區(分片),但并非設計為這樣做。 實際上,擴展SQL數據庫可能會導致其失去某些一致性。 另一方面,NoSQL數據庫在設計時考慮了水平分區。
4.匯總
匯總數據是作為一個單元存儲的數據的集合。 眾所周知,NoSQL將所有數據存儲在一條記錄中-這是一個面向集合的數據庫。
NoSQL的缺點
1.不適用于更新
由于NoSQL數據庫保持軟狀態,因此它們不能保證其副本之間的一致性。 如果有大量的更新/刪除操作,雖然數據可能可用,但它們并不相互一致。
另一方面,SQL數據庫可以更好地處理更新/刪除操作的量,因為它們鎖定行以確保事務是隔離的,因此在每次事務之后保持一致。 考慮到這些屬性,我認為像Robinhood這樣的股票交易應用程序會比NoSQL更喜歡SQL。
另一方面,由于SQL中的關系,表中的記錄可以輕松地引用另一個表中的行ID。 例如,如果要更改部門的位置,則該修改可以限于"部門"表。 另一方面,NoSQL數據庫必須遍歷所有記錄,更改每條記錄的位置。
2.未針對過濾進行優化
等等,讀起來不是更快嗎? 是的,當您查詢整個記錄時,它們會更快,因為記錄中所有數據都可用。 但是,如果要使用某些過濾器查詢記錄,則對于NoSQL數據庫而言,這將變得相對昂貴,因為必須首先獲取所有記錄,并且在返回之前將過濾器應用于每個記錄。 另一方面,SQL數據庫通過對列進行檢查來更有效地進行工作過濾。
3.聯接很昂貴
由于NoSQL表之間沒有隱式關系,因此解析記錄并通過鍵將它們聯接起來的開銷很大。 SQL數據庫可以通過引用另一個表的行的ID輕松地做到這一點。
最后的話
在使用分布式系統時,我們必須了解,通常沒有唯一的最佳解決方案。 相反,我們需要了解我們的需求,并找出哪種折衷方案最適合我們的情況。
我仍在學習這些主題。 希望共享這些內容將增強我自己的知識。 如果有任何更好的解釋,請隨時發表評論。
如果您已經做到了這一點,感謝您的閱讀!
(本文翻譯自Zeng Hou Lim的文章《An Introduction to NoSQL Databases》,參考:https://medium.com/better-programming/introduction-to-nosql-databases-7f6ed6e055c5)