如果外键/级联删除不好,为什么要使用具有该功能的数据库服务器?

rah*_*286 8 mysql nosql foreign-key referential-integrity

我注意到 wordpress/rails 等不使用外键约束或从数据库中级联删除功能。相反,他们在 PHP/Ruby/脚本级别处理这个!

我已经阅读了这个这个。大多数反对外键约束的论点都涉及性能、多线程、锁定、可伸缩性等。

假设反对外键的论点是有效的,我的问题是:

  1. 如果外键不好,为什么 WordPress/Rails/etc 使用支持外键的 sql-server?他们会从 MySQL 转向 NoSQL 类型的服务器吗?
  2. 另一方面,应用程序能否以某种方式编码以利用外键功能而不会遇到问题?
  3. 如果我们仅将数据库用于应用程序/脚本层的存储和管理“关系”,那么 noSQL/redis 会更好吗?

Tom*_*Tom 13

让我们从您的第一个链接开始。它说得很清楚:

在具有参照完整性的大型数据库上工作表现不佳。

这是正确的。只是您可能不知道“大型数据库”是 TB 级大小,表中有数十亿行。一个简单的选择可能会级联成数以亿计的相关元素被删除,然后就会出现性能问题。

对于常规的小型数据库(例如 wordpress 日志或大多数 CMS)而言,这不是问题 - 如果您执行诸如 facebook 之类的操作或处理金融模拟数据,它就会变成一个问题。我经常处理数十亿行表并删除在事务之外的存储过程中以 x 为批处理工作 - 因为最终删除可能很容易清理一些亿行。

他们会从 MySQL 转向 NoSQL 类型的服务器吗?

几乎不。当专业人员适当地使用它们时,它们会很有用。

另一方面,应用程序能否以某种方式编码以利用外键功能而不会遇到问题?

是的。

如果我们仅将数据库用于应用程序/脚本层的存储和管理“关系”,那么 noSQL/redis 会更好吗?

我曾经在一家不使用参照完整性的银行进行技术升级的应用程序审查(以提高性能)。将数据加载到 SQL Server(应该替换其老化的 Adabas 安装)中失败,并违反完整性约束。碰巧 40% 的历史记录是无效的,因为某些*删除了不再使用的查找表值(例如旧客户分类代码,它被所有活动客户替换,而不是旧客户)。没有出现参照完整性警告。结果是一些人被解雇了,一个问题被困在了解决方法中,并且在上面构建了一个部分无用的数据仓库。

管理应用程序/脚本层的关系到此为止。错误会发生。数据很有价值,应用程序会发生变化。

大多数抱怨 SQL 级别功能的人会更倾向于阅读有关它们的书,并尝试理解它们,而不是抱怨。可悲的是,互联网上的许多建议都是由甚至拒绝阅读文档的人写的。总是要小心。大多数对 NoSql 的建议都强烈地基于无知。

  • 确切地。这就是级联删除的好处。但 otoh 想象一下,你删除一个帖子需要几个小时,因为它有 5 亿条评论;) 这就是性能问题出现的地方。像所有 SQL 相关的东西一样,它需要在扩展时进行规划和思考。当您遇到大量数据时,您最好使用存储过程来缓慢删除更受控制的内容。 (2认同)
  • 是的,但是您输入了一个删除 1 行的 sql,然后等待数小时 - 数据库中的锁是您没想到的。然后人们对缓慢的数据库呼叫支持和诅咒。这是开发人员的无知,但这是您必须解决的问题。不是每个 - 甚至是大型 - 数据库都可以在不中断服务的情况下处理 5 亿行删除。执行删除操作的网站可能会阻止该页面数小时,直到它被提交。尝试自己考虑这些场景——这是开发人员工作的一部分。 (2认同)
  • 完全是的。基本上 - 级联是完美的,只要它们不会改变太多特性。如果删除 1 行变成一个小时的等待,就是这种情况。我们不要陷入数据库日志大小管理、内存消耗等问题,如果简单的删除变成多 GB 的更改,可能也需要计划。 (2认同)
  • @rahul286 这里的问题不在于 SQL 需要更加小心以提高性能,而只是因为纯粹的数学原因,某些问题无法更快。SQL 是关于搜索和排序结构化数据的。要搜索堆,您必须触摸每个项目直到找到为止。如果有人为您创建了一个有序列表(大致是 SQL 中的一个索引),那么您会快得多,但仍然需要时间。但就是这样。没有什么可以大大降低这个“列表查找时间”。也许小调整,但没什么大不了的。SQL 处于这种状态。它很快,所有限制都是“天生的”。 (2认同)
  • @rahul286 NoSQL 风格的存储基本上就是 SQL 中的“索引”。它们本身无法确保数据完整性——这就是它们比 SQL 更快的原因。通常您使用 NoSQL 存储来支持关系/SQL 存储。最好的例子是 laaarge 网站的搜索引擎。所有真实数据都在某个 SQL 数据库中。对其进行搜索很慢(尤其是使用 LIKE 或 REGEX)。然后获取数据,为 NoSQL 存储做好准备,然后在 NoSQL 存储而不是 SQL 存储上执行搜索功能。NoSQL 以一种有用的方式“复制”SQL 存储以提高速度。 (2认同)
  • @rahul286 如果 NoSQL 存储崩溃 - 没人关心。您可以从 SQL 存储中重建它(确保数据完整性并始终拥有真实数据)。NoSQL 通常用作“第 3 方索引”以支持 SQL 索引不足的 SQL 引擎。 (2认同)