AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 290803
Accepted
vvs14
vvs14
Asked: 2021-05-01 04:04:35 +0800 CST2021-05-01 04:04:35 +0800 CST 2021-05-01 04:04:35 +0800 CST

关系数据库中的不一致

  • 772

当使用术语一致性时,我通常会感到困惑。NoSQL 教程总是指读取,而关系教程指的是一致状态(确保引用完整性约束)

当数据分布在多个服务器上时(例如 1 主 - n 从配置)

  1. 关系数据库是否确保读取的一致性?我的意思是提交的写入可以立即被其他事务读取?我怀疑没有给定网络,使关系数据库成为最终一致的数据库。
  2. 关系数据库是否能很好地确保参照完整性约束?
rdbms nosql
  • 3 3 个回答
  • 306 Views

3 个回答

  • Voted
  1. Best Answer
    J.D.
    2021-05-01T04:32:03+08:002021-05-01T04:32:03+08:00

    直接回答您的问题:

    1. “关系数据库是否确保读取的一致性? ”

    A:简而言之,当定义ACID 主体,特别是一致性部分时,早在分布式数据成为关系数据库的概念之前。所以从这个角度来看,一致性是自动的,因为只有一个服务器在运行。一旦提交了事务,服务器立即与自身保持一致,关于该事务和与之相关的所有约束,没有其他服务器可以同步和提交。(请注意,这仅集中在ACID 主体中的一致性含义的一部分,以与 OP 关于分布式数据的问题的相关性。)

    现在有许多符合 ACID 的关系数据库系统,旨在处理跨多个服务器的分布式数据。但是,让我们暂时以 Microsoft SQL Server 及其AlwaysOn 可用性组功能为例。此功能旨在通过将数据从主服务器同步到其他辅助服务器来实现高可用性/灾难恢复功能。它也符合 ACID,因为它可以配置为确保跨服务器的一致性(当设置为同步时模式)。关于它如何工作的一个非常基本的解释是,只有在事务从主服务器同步到所有辅助服务器后,它才会完全提交事务。这保证了所有服务器在任何时候的一致性,并允许它在分布式服务器环境中保持ACID 兼容。

    1. “关系型数据库能很好地保证参照完整性约束吗? ”

    答:实际上并没有一种方法可以量化地回答这个问题,但一般来说,是的。参照完整性是使用关系数据库的要点之一。当有一个关系定义良好的模式,并定义了适当的约束(例如外键)时,关系数据库可以保证始终强制执行这些约束的规则,以确保它始终强制执行适当的引用完整性。这与一致性的定义以及关系数据库如何与ACID兼容有关。

    • 4
  2. ypercubeᵀᴹ
    2021-05-01T06:15:39+08:002021-05-01T06:15:39+08:00

    我将尝试仅回答 1:

    当数据分布在多个服务器上时(例如 1 主 - n 从配置)

    1. 关系数据库是否确保读取的一致性?我的意思是提交的读取可以立即被其他事务读取?我怀疑没有给定网络,使关系数据库成为最终一致的数据库。

    这取决于 DBMS 和 DB 拓扑的配置设置,但答案可以是:
    是的,关系 DB 不是最终一致的,而是真正一致的。

    例如,在 Postgres 中,有几个synchronous_commit设置允许不同级别的一致性。来自文章你应该在 PostgreSQL 中使用同步复制吗?:

    synchronous_commit=remote_applysynchronous_standby_names— 只有在定义的备用数据库确认事务已在 WAL 之外应用到数据库本身之后,主数据库才会将提交发送到应用程序。

    基本上它说提交只有在写入副本(“奴隶”)后才可读。

    Postgres 和所有其他允许类似行为的主要 DBMS 中也有“master-master”配置,具有多个写入节点(“master”)。

    • 3
  3. Simon Richter
    2021-05-01T14:19:10+08:002021-05-01T14:19:10+08:00

    读取一致性取决于活动的事务隔离级别。在这里,您需要权衡一致性要求与性能和其他错误状态。

    大多数应用程序都摆脱了相当“弱”的隔离保证,因为 JOIN 仍然不会返回不一致的数据。例如,

    CREATE TABLE one (a INTEGER PRIMARY KEY, b INTEGER NOT NULL);
    CREATE TABLE two (c INTEGER PRIMARY KEY, d INTEGER NOT NULL REFERENCES one(a));
    

    您通常会使用代理键插入值,例如

    INSERT INTO one VALUES(nextval('a_seq'), '5');
    INSERT INTO two VALUES(nextval('c_seq'), currval('a_seq'));
    

    从技术上讲,这是两个事务,因此即使在最高隔离级别上它们也变得独立可见,但是如果您的查询要求

    SELECT FROM one JOIN two ON a = d;
    

    你仍然只会得到完整的套装。对于大多数应用程序来说,这已经足够了,并且避免更强隔离级别所需的额外应用程序逻辑(由于并发事务,事务可以看似随机地被拒绝)是可取的。

    数据库将拒绝导致违反约束的事务,但允许事务中间的非法中间状态。例如,

    DELETE FROM one WHERE a = 1;
    DELETE FROM two WHERE d = 1;
    

    如果存在这样的行,则会出错one;BEGIN反向顺序的相同事务是可以的,就像用and将两个语句包装成一个事务一样COMMIT。如果你喜欢危险的生活,你也可以给出一个ON DELETE CASCADE规则,删除所有依赖的行。

    从数据库服务器的角度来看一致性:查询被发送到服务器,在那里进行处理,并返回结果集。网络延迟与一致性无关:两个不相互通信的客户端无法找出哪个客户端先发送了查询,因此服务器选择任意顺序。

    如果两个客户端确实互相交谈,并且一个通知另一个它刚刚插入数据并从服务器获得了确认,那么第二个客户端将能够在其查询中看到数据。

    复制的数据库仍将保留此属性,但更高的隔离级别会导致更严格的性能损失,因为确认事务需要所有节点确认没有其他活动事务与它发生冲突,并且获得这种共识需要时间。

    在更高的隔离级别下,已经开始新事务的客户端BEGIN可以对数据库的冻结视图执行SELECT查询,该视图不反映任何其他正在运行的事务,但任何读取的数据都将被锁定直到事务结束,使得并发写入失败。

    从应用程序程序员的角度来看,您通常会在 DBMS 中执行修改,而不是检索数据、修改数据并将其写回,例如

    UPDATE accounts SET balance = balance - 1 WHERE user = '3';
    

    这很好地避免了与其他事务的一致性问题,即使在较低的隔离级别下,也可以让您摆脱锁定:两个这样UPDATE的查询可以从不同的客户端发送,并且 DBMS 可以在内部解决它们,并且不会因网络周转时间而延迟。

    约束不必是参考的:balance需要为正的约束将为每个事务验证,如果只能执行一个,则返回第二个错误(对于并发事务,哪个是“第二个”是任意的)。

    这些约束检查是您想要使用 RDBMS 的主要原因之一,但这仅限于可以表示为有限数量的表和适当索引之间的关系的数据结构,因此例如很难表达以允许高效查询的方式绘制图形或层次结构,这就是 NoSQL 的用武之地。

    • 2

相关问题

  • 与 PostgreSQL 和 MySQL 相比,Firebird 数据库有多成熟?

  • Cassandra 的“phpMyAdmin”

  • RDBMS 上的“索引”是什么意思?[关闭]

  • NoSQL 和传统的 RDBMS 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve