你绝对需要数据库中的外键吗?

时间:2011-03-30 23:46:12

标签: database database-design foreign-keys

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

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

12 个答案:

答案 0 :(得分:24)

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

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

关于你的评论:

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

有人最终会犯错误。没有人是完美的。此外,如果你带来一个新的人,你并不总是能够确定他们写作的完美能力。代码。

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

答案 1 :(得分:9)

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

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

答案 2 :(得分:6)

外键对于确保完整性非常有用,即使你相信你的开发人员永远不会(!)犯错误,通常也值得拥有它们。

外键也可以作为文档,因为你可以看到与什么有关。此信息通常也由工具使用,例如用于生成报告,从表定义创建数据集,对象关系映射器等。即使您今天不使用任何这些信息,使用FK也可以更容易地使用此路径后面。

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

如果你考虑绕过FK,那么只有你有可笑的高负荷。

编辑:更新的答案,包括其他答案(报告,级联)中的点。

答案 3 :(得分:6)

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

人们提出这个问题的不足之处始终是表现。

外键为优化器提供了更多信息,并且可能会产生更好的执行计划。它不像特定查询在启用约束时会快%%,更像是由于执行计划错误而有效地消除了所有类别的问题。您还可以使优化器以不受约束的方式重写查询(例如,连接消除)。

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

传播这个词;)

答案 4 :(得分:6)

你说

  

但是比如说程序员   做好保存数据的工作   完整性

您正在寻找的表达方式是,“我100%确定每个程序员和每个数据库管理员都会完全手动保留数据完整性,无论应用程序接触到哪个数据库,无论数据库有多复杂,从现在开始直到它退役的时间。“

答案 5 :(得分:5)

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

他们随时为您提供帮助。通过级联更新和级联删除使生活更轻松,以保证不违反约束。

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

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

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

答案 6 :(得分:3)

使用报表生成器和数据分析工具时,外键可以让生活变得更加轻松。只需选择一个表格,查看include related tables框和 BAM!您已经建立了报告。好的,这并不容易,但在这方面可以节省时间。

答案 7 :(得分:3)

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

我从您的一条评论中了解到,您提出问题的动机是您认为省略密钥可能会使开发期间更容易发展数据库设计。根据我的经验,你错了。我发现在开发的早期阶段,通过约束来限制更多实际上更好。如果有疑问,请创建约束,因为它比创建约束更容易删除约束。删除约束往往会比添加约束更少,并且通常需要更少的测试和更少的代码更改来实现。

答案 8 :(得分:2)

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

答案 9 :(得分:2)

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

我今天遇到了同样的问题,发现很多文章都在讨论为什么不必在线使用外键。但到目前为止,这里的 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 不适用于在线架构迁移。

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