永远不要忘记酸!
#sql #database #systemdesign

我们通常会忘记酸性属性如何单独起作用,因为这些是关系数据库的核心,我们重要的是,我们知道它们的重要性,确保团队成员之间的清晰沟通并有效地使用这些属性

原子能:全部或全无。此属性确保在交易中进行所有更改,或者如果某事失败,则所有更改都将恢复。

一个很好的例子,看看为什么要有原子性是货币转移至关重要。

想象一下将资金从银行帐户a转移到B。交易涉及从a中减去余额并将余额添加到B。如果这些更改中的任何一个部分应用于数据库,它将导致不借方或信用的钱,具体取决于何时失败。

一致性:此属性确保数据库中的每个数据都是正确的。任何添加错误数据的尝试都会导致故障。

不一致的数据是什么样的?帐户的余额可以更新为负面,这在孤立数据的实际剩余剩余(例如博客文章的评论)中是不可能的。如果删除了博客文章,则还必须从数据库中删除其评论

通过定义诸如外键约束,检查约束,删除级联,更新级联等规则来确保正确性。

隔离:此属性可确保不超过一项交易可以写(独家锁定)或读取(共享锁定)对特定行的访问,以防止错误更新数据和幻影读取。

请在同一帐户上同时在同一帐户上进行两个或多个转移的情况,而无需隔离,数据库中错误的金额更新的可能性很高,并且在借记的金额与信用额度

之间会有不匹配。

耐用性:此属性确保一旦交易提交,变更将在任何中断,崩溃和失败中生存下来,这意味着任何作为成功交易的一部分所经过的写作的任何写作都不会突然消失。

一个典型的例子是您在亚马逊上下达的采购订单,该订单应继续存在,即使其数据库面对中断后,该订单仍不受影响。因此,为了确保某些事情发生崩溃,必须将其存储在非挥发性存储中,例如磁盘。这构成了耐用性的核心思想。

现在您知道了什么是酸性特性以及如何有效使用它们,您是否想知道它们是如何在引擎盖下实施的?

原子能:

大多数数据库都使用记录实现原子。当交易开始时,引擎开始记录文件中的所有更改。当发动机收到提交时,然后将这些更改永久应用。如果它收到回滚或发生某些错误,该日志文件将被丢弃,因此没有更改。

另外,也可以通过在开始交易之前保留数据副本并在回滚期间使用该数据来实现原子。

一致性:

在将更改应用于数据时,在运行时检查诸如主键,外键和数据类型检查之类的完整性约束。

级联操作,即在修改包含外键数据的数据时将执行的操作与运行事务同步执行。大多数数据库引擎还提供了一种使它们异步的方法,使我们能够保持交易更精简。

隔离:

更改任何行之前的交易会在该行上锁定(共享或独家),不承担任何其他交易以对其采取行动。其他交易可能必须等到第一笔交易要么要进行回滚。

粒度和锁定范围取决于配置的隔离级别。每个数据库引擎都支持多个隔离级别,这决定了锁定的严格性。 4个隔离水平

序列化:

可序列化隔离水平提供了最严格的交易隔离。此级别模拟所有犯有交易的串行交易执行;好像交易是在一个接一个地执行的,而不是同时执行的。

可重复的读数:

可重复的读取级别仅在交易开始之前看到所提供的数据。它从未看到通过并发交易在交易执行期间所做的未投入的数据或更改。

阅读委托:

读取的是PostgreSQL中的默认隔离级别。当交易使用此隔离级别时,选择查询(无需更新/共享子句)就会看到查询开始之前所做的数据;它从未看到通过并发交易在查询执行期间所做的更改。

读取不合格:

无需读取隔离级别允许应用程序访问其他交易的不承担变化。此外,除非该应用程序试图更改或丢弃表,否则UR不会阻止其他应用程序访问正在读取的行。

耐用性:

实现耐用性的最基本方法是使用快速交易日志。对实际数据进行的更改首先在单独的交易日志上冲洗,然后进行实际更新。

此冲洗后的交易日志使我们能够重新启动期间重新加入并重建交易,并将系统的状态重建到发生故障发生之前的状态 - 通常是数据库的最后一致状态。写入交易日志的写入是通过保持文件附加量的快速进行,从而最大程度地减少了磁盘的搜索。