nas*_*kin 5 postgresql foreign-key relational-theory
今天早些时候,我与我的专业同行就我们公司数据库中的外键话题引发了一场相当意外的辩论。简而言之,一位比我年长的软件工程师说他不喜欢我对我们的一个存储库所做的提交,因为我在两个表之间实现了外键关系。他的论点是他不喜欢外键,因为它们限制了可以插入数据库的数据,他认为这会使数据库更难使用。(注意:他的论点一般反对外键,而不仅仅是我在我们的应用程序中提出的轶事外键约束。他认为外键约束是现代关系数据库系统中的一个设计缺陷。)
此时,我完全措手不及,我们的老板暂时选择站在高级开发人员一边,要求我从我正在处理的错误修复的实现中删除外键。我正在修复的错误实际上源于使我们的 ORM 感到困惑的关系不一致(这本身还有一些不足之处,但这是一个不同的故事),虽然我试图向我的团队解释这一点,但每个人都站在高级dev & 我被告知要回到绘图板并重新实现我的数据库修复,而不依赖于外键约束。换句话说,我被要求在没有 RDBMS(posgres,如果重要的话)的内置关系管理工具的情况下进行关系管理。
我重申这不是修复错误的正确方法,此时我的老板告诉我讨论占用了太多时间,如果我想辩论正式 FK 约束的优点,我需要以后再做……我打算这样做,但我也觉得我的任务是争论为什么水是湿的。
当我进入这场辩论时,我想用尽可能多的事实来支持外键的使用。我知道实施合理的 FK 约束:
......但我想知道在这个主题上是否还有其他我可能遗漏的要点,我应该用这些要点来应对这场辩论。我应该确保向我的老板和同事提出哪些其他好处?(或者真的有范式转变远离 FK 约束,当它发生时我一直把头埋在石头下?)
我没有足够的观点来评论,所以一个答案。
我的天啊。我感受到你的痛苦;-)
是的,人们发现外键约束确实很痛苦。但如果没有它们,您就必须审核寡妇和孤儿的数据,否则您完全有可能得到糟糕的汇总结果。至少,你并不真正知道你的结果的有效性。是否下降了 0.001%?2%?很难说……你得进去搞清楚垃圾数据的级别。
从人类的角度来看,好吧,我明白,约束可能是一种痛苦。这是一种剧烈的疼痛,因为它会在插入点阻碍您。(这就是重点。)如果规则不严格,你就会遭受痛苦,但它会被推迟。说到这里,因为我在这里看到了 Postgres 标签,所以有几件事需要了解。首先是可延期约束。对于这种情况来说,这是一个非常有价值的功能。插入一个子级只是为了将其踢回确实可能很痛苦,因为当您很快要在同一事务中添加该父级时,该父级还不存在。解决这个问题有点繁琐和乏味。(或者感觉可能是这样。)使用延迟约束,FOREIGN KEY 仍然会被强制执行,但要等到事务结束时才会强制执行。因此,如果有帮助的话,您可以按照不太严格的顺序添加记录。这是关于这个主题的一篇文章,看起来相当详尽,如果你看的话,你可以找到很多其他内容:
https://begriffs.com/posts/2017-08-27-deferrable-sql-constraints.html
其次,就其价值而言,您还获得了 ON UPDATE CASCADE 支持,尽管需要它通常是设计中存在问题的迹象。
哦,对于要点来说,正式定义的常量会进入有关系统的元数据中。因此,任何知道如何解释数据的自动工具都可以为您做更多的事情。例如:
在此处添加编辑并提供可能有帮助的建议。意见都很好,但有时证据更好。为此,运行一些探索性查询来了解当前数据的运行状态怎么样?你可能会发现,即使没有服务器端的限制,数据也没有问题。有些人就是非常擅长不搞砸。话又说回来,可能会一团糟。这是我脑海中浮现的一个问题,我确信它可以改进:
select count(*)
from child
tablesample bernoulli(5) -- If you're only after an estimate, TABLESAMPLE is your friend.
left join parent on (child.parent_id = parent.id)
where parent.id is null
Run Code Online (Sandbox Code Playgroud)
PS 我曾经输掉过同样的争论,很大程度上是因为我当时不知道延迟选项。
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |