我记得在播客014中听到Joel Spolsky提到他几乎从未使用过外键(如果我没记错的话)。然而,对我来说,它们对于避免数据库中的重复和后续数据完整性问题非常重要。

人们是否有一些可靠的理由(以避免与Stack Overflow原则一致的讨论)?

编辑:“我还没有创建外键的理由,所以这可能是我真正建立一个外键的第一个理由。”


当前回答

Wowowo... Answers everywhere. Actually this is the most complicated topic I have ever encountered. I use FKs when they are needed but on production environment I rarely use them. Here is my whys I rarely use the Fks: 1. Most of the time I am dealing with huge data on small server to improve performance I need to remove the FKs. Because when you have FKs and you do Create, Update or Delete the RDBMS first check if there no constraint violation and if you have huge DB that could be something fatal 2. Sometimes I need to import data from others places and because I am not too sure of how well structured they are, I simply drop the FKs. 3. In case you are dealing with multiple DBs and having reference key in an other DB will not go well(as for now) until you remove the FKs (cross database relations) 4. They was also a case when you write an application which will seat on whatever RDBMS or you want your DB to be exported and imported in any RDBMS system in this case each specific RDBMS system has his own way of dealing with FKs and you will probably be obliged to drop the use of FKs. 5. If you user RDBMS platform (ORMs) you know that some of them offer their own mapping depending on the solution and technicality their offer and you don't care about creating the tables and their FKs. 6. Before the last point will be knowledge to deal with DB that has FKs and the knowledge to write an application that does all the Job without the need of FK 7. Lastly as I started saying it all depend on your scenario, in case knowledge is not a barrier. You will always want to run the best of the best you can get!

谢谢大家!

其他回答

我可以看到使用外键的一些原因(有人提到,孤立行很烦人),但我也从不使用它们。对于一个相对正常的DB模式,我不认为它们是100%需要的。约束是好的,但我认为通过软件来实施约束是更好的方法。

亚历克斯

澄清数据库是一个没有主键或外键的商业数据库示例。

http://www.geekinterview.com/question_details/18869

有趣的是,技术文档花了很大的篇幅来解释表是如何关联的,用什么列来连接它们等等。

换句话说,它们本可以使用显式声明(DRI)连接表,但它们选择不这样做。

因此,澄清数据库充满了不一致,性能不佳。

但我认为它使开发人员的工作更容易,不必编写代码来处理引用完整性,例如在删除或添加之前检查相关行。

我认为,这就是关系数据库中没有外键约束的主要好处。它使开发变得更容易,至少从不顾一切的角度来看是这样。

我还认为外键在大多数数据库中是必要的。唯一的缺点(除了强制一致性带来的性能损失之外)是使用外键允许人们编写假定存在功能外键的代码。这绝不应该被允许。

例如,我看到有人编写了一些代码,将插入插入引用表中,然后尝试将插入插入引用表中,而不验证第一次插入是否成功。如果稍后删除外键,则会导致数据库不一致。

您也不能在更新或删除时假设特定的行为。无论是否存在外键,您仍然需要编写代码来执行您想要的操作。如果您假设删除是级联的,但实际上它们不是级联的,那么您的删除将失败。如果您假定对引用列的更新被传播到引用行,但实际上没有,那么您的更新将失败。出于编写代码的目的,最好不要使用这些特性。

如果打开了这些特性,那么您的代码无论如何都会模仿它们,并且会损失一些性能。

所以,总结....如果需要一致的数据库,外键是必不可少的。在您编写的代码中,永远不应假定外键存在或起作用。

我一直认为不用它们是懒惰的表现。我被教导应该一直这样做。但后来,我没有听乔尔的讨论。他也许有充分的理由,我不知道。

我只知道Oracle数据库,不知道其他数据库,而且我知道外键对于保持数据完整性是必不可少的。在插入数据之前,需要建立一个数据结构,并且建立正确的数据结构。当这一步完成时——所有的主键和外键都创建好了——工作就完成了!

意思是:孤立的行?不。这辈子都没见过。除非一个糟糕的程序员忘记了外键,或者他在另一个层次上实现了外键。在Oracle的环境中,这两者都是巨大的错误,会导致数据复制、孤儿数据,从而导致数据损坏。我无法想象一个没有强制FK的数据库。在我看来是一片混乱。这有点像Unix权限系统:假设每个人都是root用户。想想混乱吧。

外键是必不可少的,就像主键一样。这就像是说:如果我们移除主键会怎样?那么,整个混乱将会发生。这是什么。不能将主键或外键的职责移到编程级别,但必须移到数据级别。

缺点呢?是的,当然!因为在插入时,会有更多的检查。但是,如果数据完整性比性能更重要,那么这是显而易见的。Oracle上的性能问题更多地与索引有关,索引包含PK和FK。