【问题标题】:Downside not using sql foreign keys不使用 sql 外键的缺点
【发布时间】:2019-04-05 20:14:33
【问题描述】:

我有一个 Magento 商店(使用 MySql 数据库),只是注意到一些开发人员引入了一个自定义数据库来捕获一些结构化数据。

现在我注意到这些表没有通过外键相互链接,而是添加了一个列,例如priceListID = 01124 与价目表上的 Id 相同。因此,必须通过触发我假设的不同选择语句在代码中将数据链接在一起。

现在我想知道这是否需要尽快修复,或者实际上是否可以不使用数据库级别的外键将数据链接在一起? 这样做有什么缺点,是否有一些好处(比如灵活性?)

希望你能帮我解决这个问题!非常感谢!

【问题讨论】:

  • 外键有助于数据完整性,但并非绝对必要。如果您担心完整性,请考虑添加它们。

标签: php mysql sql database magento


【解决方案1】:

将此类约束保存在数据库中并没有什么好处:

  1. 性能。如果将大多数约束(例如外键)存储在靠近数据的数据库中,则可以更好地实现。您想通过额外的select 检查数据完整性吗?您必须向数据库发出额外的请求。这需要一些时间。
  2. 如果您有多个应用程序可以与您的数据库一起使用,该怎么办?您必须编写代码来检查所有这些中的数据完整性,这意味着额外的费用。
  3. 同步。当您通过附加选择检查数据完整性时,其他一些用户可能会同时删除此数据。你不会知道的。当然,这些检查是可以正确执行的,但这仍然是您必须做的额外工作。

对我来说,这都是一种糟糕的、不可扩展的设计,会带来很多问题。数据完整性是构建数据库的目的。并且这些类型的验证应该保留在数据库中。

【讨论】:

  • 感谢您的回复!关于将数据与未连接的表连接起来,是否有任何性能衡量这可能会慢多少,或者如果我通过 SQL 语句连接数据,速度是否相同?
  • @user3122136,如果您在连接列上提供适当的索引 - 在性能方面不会有太大差异。但是您仍然对存储在这些表中的数据没有任何限制。当您想在对数据应用某些操作之前验证数据时,您将面临性能问题。这些是完全不同的东西。
【解决方案2】:

根据您的描述,我了解到表格确实功能相关,因为它们共享一条共同的信息(新表格中的priceListID 与原始表格中的id 相关)。一方面,这种设置仍然允许编写将表连接在一起的查询。

但是,不创建外键来表示该关系的缺点是,从数据库的角度来看,无法保证关系的一致性。例如,可能会在新表中创建记录,而 priceListID 在原始表中不存在。也可以删除旧表中的记录,而新表中存在相关记录,从而将孩子变成孤儿。

作为结论:通过不使用外键,开发人员仅依靠应用程序来维护数据完整性。不使用 RDBMS 提供的内置特性来保护数据一致性并没有明显的好处,而且开发人员很可能只是忘记了表定义的关键部分。我建议与他们交谈并建议他们创建缺少的外键(除非他们能清楚地解释为什么他们没有这样做)。

这应该很简单:

ALTER TABLE newtable
    ADD CONSTRAINT fk_new_to_original_fk 
    FOREIGN KEY (priceListID ) 
    REFERENCES originaltable(id);

请注意,这要求引用列中的所有值在父表中都可用。

【讨论】:

  • 感谢您的简要说明!添加这些外键需要做很多工作吗?现在已经有大量数据,真的有可能吗?我假设数据完整性不会是 100%(并且不需要,因为它不是业务关键),但将来我会努力争取更好的数据质量。
  • @user3122136:欢迎!添加外键可以通过简单的 SQL 语句来完成,但它要求数据在执行时是一致的。我更新了我的答案。
  • 谢谢!任何方式也可以“自动添加”另一个表中所有不存在的记录?自动添加时不需要填写任何字段,只需创建即可创建。
  • @user3122136:见this SO post
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多