【问题标题】:Do you absolutely need foreign keys in a database?您绝对需要数据库中的外键吗?
【发布时间】:2011-07-26 12:18:06
【问题描述】:

我想知道外键在数据库中到底有多有用。本质上,如果开发人员知道不同表所依赖的键,他们就可以像有外键一样编写查询,对吧?

另外,我确实看到了外键约束如何帮助防止各种数据完整性错误,但是比如说,程序员在保持数据完整性方面做得很好,外键真的有必要吗?

【问题讨论】:

  • 您是在问外键有多有用或外键约束有多有用?

标签: database database-design foreign-keys


【解决方案1】:

如果您不关心参照完整性,那么您是对的。但是....您应该关心引用完整性。

问题是人们会犯错误。电脑没有。

关于您的评论:

但是比如说,程序员做得很好 保持数据完整性

总会有人犯错。没有人是完美的。此外,如果您引入新人,您并不总是确定他们是否有能力编写“完美”的代码。

除此之外,您将失去执行级联删除的能力以及具有已定义外键允许的许多其他功能。

【讨论】:

  • 我希望在 95% 的时间内定义外键。不这样做的原因是如果不再使用某些功能,则更容易丢弃表。在项目的早期阶段制作和丢弃大量表格是很常见的。但是你可能会被设计不佳的外键卡住,这就是我提出问题的动机。
  • 难怎么办? DBMS 说你有依赖记录?如果这是真的,那么这是一件非常好的事情。否则,您将在永恒的剩余时间里漂浮着孤立的垃圾数据。
【解决方案2】:

我认为假设程序员将始终保持数据完整性是一个冒险的假设。

您没有理由不创建外键,并且能够保证完整性而不是仅仅希望完整性就足够了。

【讨论】:

    【解决方案3】:

    在数据库中不使用参照完整性就像在汽车中不使用安全带一样。它将为您从 A->B 提供可衡量的改进,但仅在最极端的情况下才会产生“真正的”差异。除非你真的不得不冒险,否则为什么要冒“风险”?

    人们问这个问题的根本原因始终是性能。

    外键为优化器提供了更多可使用的信息,并且可能会产生更好的执行计划。这不像一个特定的查询会在启用约束的情况下提高 %%,它更像是你有效地消除了由于执行计划错误而导致的所有问题。您还可以让优化器以没有约束的情况下无法实现的方式重写查询(例如连接消除)。

    从这里开始,我想开始一个神话,即参照完整性总能提高数据库的性能。我相当有信心,如果 100 个人在设计他们的数据库时使用了完整的完整性检查,那么实际上只有不到 5 个人会考虑花费 1 秒钟的时间来出于性能原因禁用它们。在这 5 个人中,将有接近 0 个人发现他们需要禁用 100% 的约束。

    【讨论】:

      【解决方案4】:

      外键作为确保完整性的一种手段是非常宝贵的,即使您相信您的开发人员永远不会(!)犯错误,拥有它们的成本通常是值得的。

      外键还可以用作文档,因为您可以看到与什么相关的内容。这些信息通常也被工具使用,例如生成报告、从表定义创建数据集、对象关系映射器等。即使您今天不使用任何这些,拥有 FK 也会更容易走这条路稍后。

      外键还允许您定义级联规则,例如可用于在删除一个表中的一行时,删除相关表中的关联记录。

      只有当你的负载高得离谱时,你才应该考虑绕过 FK。

      编辑:更新答案以包含来自其他答案(报告、级联)的点。

      【讨论】:

        【解决方案5】:

        你说

        但是比如说,程序员 做好数据保存工作 诚信

        您正在寻找的表达式是,“我 100% 确信,无论什么应用程序访问该数据库,无论数据库变得多么复杂,从现在到它退役的时间。”

        【讨论】:

          【解决方案6】:

          您不必使用它们,但为什么不用呢?

          他们是来帮忙的。从通过级联更新和级联删除让生活更轻松,到保证不违反约束。

          也许应用程序尊重约束,但明确指定它们不是有用吗?你可以记录它们,或者你可以把它们放在数据库中,大多数程序员都希望找到他们应该遵守的约束(我认为这是一个更好的主意!)。

          最后,如果您需要将不通过前端的数据导入此数据库,您可能会不小心导入违反约束并破坏应用程序的数据。

          我绝对不建议跳过数据库中的关系

          【讨论】:

            【解决方案7】:

            在使用报表生成器和数据分析工具时,外键让生活变得如此轻松。只需选择一个表格,选中 include related tables 框和 BAM!,您的报告就完成了。好吧好吧,这并不容易,但他们确实在这方面节省了时间。

            【讨论】:

              【解决方案8】:

              使用约束而不是应用程序逻辑来强制执行完整性,因为在一个地方(数据库)而不是在每个应用程序中维护约束通常更容易、更便宜且更可靠。

              我从您的一位 cmets 了解到,您提出这个问题的动机是您认为省略键可能会使开发过程中的数据库设计更容易演变。根据我的经验,你错了。我发现在开发的早期阶段限制更多实际上更好。如果有疑问,请创建约束,因为删除约束比创建约束要容易得多。与添加一个约束相比,删除约束往往会破坏更少的东西,并且通常需要更少的测试和更少的代码更改来实现。

              【讨论】:

                【解决方案9】:

                要说明的另一点是,当您废弃当前的用户界面并使用带有闪亮新工具的新用户界面时,您不会失去参照完整性,因为新开发人员不知道什么应该与什么相关。数据库的使用时间通常比用户界面长得多。它们还经常被多个应用程序接口使用,然后您会遇到不同接口尝试强制执行不同完整性规则的问题。

                我还要指出,我曾经有机会查看数百个数据库中的数据,但如果他们没有设置 FK,我还没有找到一个具有良好数据的数据库。这种不良数据使报告变得复杂,它使客户和其他需要或提供数据的第三方供应商的进出口变得复杂。如果坏数据是在金融领域,它也可能产生法律和会计影响。我什至记得有一次公司有数千个不良库存记录,其中存储的实际产品不再可识别(也无法识别位置),这也造成了定义财务报告所需库存价值的问题。从不知道您手头有哪些零件的角度来看,这不仅是不好的,而且它使人们可以通过从零件表中删除零件号来窃取零件而不会被抓住(这个特定的地方也没有审核.).

                【讨论】:

                  【解决方案10】:

                  人们在上面提供了一些很好的答案。但是,我没有看到提到的一个重要点是外键使您的实体关系图 (ERD) 更容易生成并且更有意义。如果没有 FK,您要么需要手动描述 ERD 上的 FK 关系(对您来说很痛苦),要么根本不需要(一旦您对隐含的 FK 关系的记忆随着时间的推移开始消退,甚至可能对您自己也很痛苦)。明确定义 FK 后,大多数从数据库对象定义自动生成 ERD 的工具将自动检测和描述 FK 关系。

                  【讨论】:

                    【解决方案11】:

                    也许问题应该是“孤儿记录有多糟糕?”。在许多情况下,孤立的记录并不会真正伤害任何东西。是的,这些记录可能会持续到时间结束,但这真的有多糟糕?级联更新或删除很少有用的功能。参照完整性听起来不错,但我认为并不像我们一直认为的那么重要。 FK 的最大好处是他们提供的文档。以我的经验,FK 的参照完整性比它们的价值要麻烦得多。

                    【讨论】:

                      【解决方案12】:

                      我今天也有同样的问题,发现很多文章都在谈论为什么你不必在网上使用外键。但到目前为止,这里的 11 个答案中有 10 个说你应该有 FK。

                      我不是数据库专家,我只是想分享一些我在网上找到的关于您何时以及为什么没有 FK 的观点:

                      来自9 reasons why there are no foreign keys constraints的一些观点:

                      • 性能
                      • 旧数据
                      • 重新加载全表
                      • 更高层次的框架
                      • 跨数据库关系
                      • 与数据库平台无关
                      • 开放更改
                      • 懒惰的建筑师
                      • 对模型保密

                      来自At GitHub we do not use foreign keys, ever, anywhere.的一些观点

                      • FK 阻碍了您对数据库进行分片。
                      • FK 会影响性能。
                      • FK 不适用于在线架构迁移。

                      注意:我没有任何意见。只是分享一些在线文章,为当前的大多数文章提供不同的答案。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-12-07
                        • 2015-06-24
                        • 1970-01-01
                        • 2012-10-31
                        • 1970-01-01
                        • 2022-01-24
                        • 1970-01-01
                        相关资源
                        最近更新 更多