SQL / NoSQL,ACID与BASE一致性模型以及CAP定理的高级概述
> Photo by fabio on Unsplash
· SQL与NoSQL数据库概述
· ACID与BASE一致性模型
· CAP定理
· NoSQL的优势与劣势
SQL代表结构化查询语言。 人们提到SQL数据库时,实际上是在指关系数据库管理系统(RDBMS)。
数据以表格形式存储。 每行由主键唯一标识,并且每行还可以具有外键,该外键是另一个表的主键。 通过外键,与另一个表形成了一个关系-因此关系数据库的概念。
SQL数据库的示例包括MySQL,PostgreSQL和Oracle数据库。
> Relationship between Student and Department Tables
NoSQL被称为"无SQL",有时也称为"不仅SQL"。 当数据库可以支持SQL类型查询时,使用后一个术语。
NoSQL数据库有四种类型:
· 文件(例如Firestore)。
· 图(例如Neo4j)。
· 键值(例如Riak,Berkeley DB)。
· 宽列(例如Cassandra,HBase)。
四种类型的数据库支持不同的数据存储方式,而不是将数据存储在SQL数据库的表中。
考虑NoSQL的一种简化方法是想象一个JSON结构。 您需要一个键才能检索值。
> JSON schematic representation of a NoSQL database
现在,您已经对这两种类型的数据库有了全面的了解,让我们看一下一致性模型,这将有助于我们了解这两种数据库之间的权衡。
当一个事务(读/写)发生时,它应该一次全部发生,或者根本不发生。 如果事务中止,则数据库不会受到影响。 同样,如果交易通过,数据库的状态应反映出更改。 本质上,它全有还是全无。
事务完成后,数据库实例(例如副本)应同时反映相同的状态。
每个事务应独立执行。 这意味着没有两个事务会引起竞争条件。 数据库在该行上设置了锁,以确保事务按顺序发生。
提交事务后,即使系统崩溃,修改也将是永久的。
ACID属性可确保在交易完成后,整个数据都是一致的。 但是,这是以锁定数据库为代价的。
NoSQL数据库在设计时考虑了规模,因此遵循BASE属性而不是ACID。
数据库倾向于数据的可用性,而不是数据的正确性。
数据库存储(例如副本)不必始终保持一致。
一段时间后,数据库存储最终将相互一致。
NoSQL数据库面向可伸缩性,因此具有更高的容错能力。 换句话说,当副本崩溃时,NoSQL数据库仍然可以返回数据,尽管不是最准确的版本。
拥有这两个一致性模型使我们可以很好地选择CAP定理,该定理指出:
分布式数据库系统只能具有3:一致性,可用性和分区容忍中的2个。
> CAP Theorem Diagram
在讨论ACID与BASE时,我们已经讨论了一致性和可用性。 我们还知道,SQL数据库更注重一致性,而NoSQL数据库则面向可用性。 那么,分区容忍度是什么?
假设在集群中,在主-主设置中有两个节点X和Y。 当我们将请求指向这些节点时,X和Y之间的连接断开,因此我们遇到了一个问题:X和Y上的数据不一定同步,并且我们不知道哪个节点具有正确的数据。 节点应如何响应请求?
· 给予回应。 优先考虑可用性,但牺牲一致性(AP),因为数据可能不一定准确。
· 不要回应。 一致性被优先考虑,因为如果数据不准确,节点将不响应,但是在过程(CP)中会牺牲可用性。
第三个组合是CA,它尊重一致性和可用性,但不能存在分区(节点之间的故障)。
规范化是将数据隔离到单独的表中以减少冗余和重复数据的过程。 SQL数据库通常采用此范例。 在前面的示例中,我们看到Student表引用了Department表中一行的ID。 如果部门的位置发生变化,我们可以简单地对Department表进行修改,而不会影响Student表。
相反,NoSQL数据库通常支持非规范化,其中可以在记录之间复制数据。 我们看到部门数据实际上是在所有记录中复制的。 由于学生和部门的数据包含在一条记录中,因此检索速度更快,因为不需要表联接(可能在SQL数据库中是必需的)。
另外,由于所有数据都存储在单个记录中,因此可以通过一次调用NoSQL数据库来完成插入数据库的操作,而不必进行多次调用来用SQL数据库更新不同的表。
向SQL数据库中的表添加新属性是一项昂贵的操作。 需要将新列添加到每一行,并且为了保持一致性(副本之间),在添加新列时需要对存储进行锁定。
另一方面,NoSQL数据库不需要严格的架构,每个记录可以具有所需的任何键/值对。
SQL数据库的设计不能很好地横向扩展。 尽管可以进行水平分区(分片),但并非设计为这样做。 实际上,扩展SQL数据库可能会导致其失去某些一致性。 另一方面,NoSQL数据库在设计时考虑了水平分区。
汇总数据是作为一个单元存储的数据的集合。 众所周知,NoSQL将所有数据存储在一条记录中-这是一个面向集合的数据库。
由于NoSQL数据库保持软状态,因此它们不能保证其副本之间的一致性。 如果有大量的更新/删除操作,虽然数据可能可用,但它们并不相互一致。
另一方面,SQL数据库可以更好地处理更新/删除操作的量,因为它们锁定行以确保事务是隔离的,因此在每次事务之后保持一致。 考虑到这些属性,我认为像Robinhood这样的股票交易应用程序会比NoSQL更喜欢SQL。
另一方面,由于SQL中的关系,表中的记录可以轻松地引用另一个表中的行ID。 例如,如果要更改部门的位置,则该修改可以限于"部门"表。 另一方面,NoSQL数据库必须遍历所有记录,更改每条记录的位置。
等等,读起来不是更快吗? 是的,当您查询整个记录时,它们会更快,因为记录中所有数据都可用。 但是,如果要使用某些过滤器查询记录,则对于NoSQL数据库而言,这将变得相对昂贵,因为必须首先获取所有记录,并且在返回之前将过滤器应用于每个记录。 另一方面,SQL数据库通过对列进行检查来更有效地进行工作过滤。
由于NoSQL表之间没有隐式关系,因此解析记录并通过键将它们联接起来的开销很大。 SQL数据库可以通过引用另一个表的行的ID轻松地做到这一点。
在使用分布式系统时,我们必须了解,通常没有唯一的最佳解决方案。 相反,我们需要了解我们的需求,并找出哪种折衷方案最适合我们的情况。
我仍在学习这些主题。 希望共享这些内容将增强我自己的知识。 如果有任何更好的解释,请随时发表评论。
如果您已经做到了这一点,感谢您的阅读!
(本文翻译自Zeng Hou Lim的文章《An Introduction to NoSQL Databases》,参考:https://medium.com/better-programming/introduction-to-nosql-databases-7f6ed6e055c5)