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

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

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


当前回答

@ emphasis——这正是导致维护噩梦的心态。

为什么,哦,为什么要忽略声明性引用完整性(其中数据至少可以保证一致),而支持所谓的“软件强制”,这充其量是一种薄弱的预防措施。

其他回答

外键对于任何关系数据库模型都是必不可少的。

From my experience its always better to avoid using FKs in Database Critical Applications. I would not disagree with guys here who say FKs is a good practice but its not practical where the database is huge and has huge CRUD operations/sec. I can share without naming ... one of the biggest investment bank of doesn't have a single FK in databases. These constrains are handled by programmers while creating applications involving DB. The basic reason is when ever a new CRUD is done it has to effect multiple tables and verify for each inserts/updates, though this won't be a big issue for queries affecting single rows but it does create a huge latency when you deal with batch processing which any big bank has to do as daily tasks.

最好避免fk,但它的风险必须由程序员来处理。

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

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

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

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

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

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

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

数据结构设计的一个好的原则是确保表或对象的每个属性都服从于一个很好理解的约束。这很重要,因为如果您或您的程序可以依赖数据库中的有效数据,那么就不太可能出现由坏数据引起的程序缺陷。您还可以花费更少的时间来编写处理错误条件的代码,并且更有可能预先编写错误处理代码。

在许多情况下,这些约束可以在编译时定义,在这种情况下,您可以编写一个筛选器来确保属性总是在范围内,或者尝试保存属性失败。

然而,在许多情况下,这些约束可以在运行时更改。例如,您可能有一个“cars”表,其属性为“colour”,初始值为“red”、“green”和“blue”。在程序执行期间,可以将有效的颜色添加到初始列表中,并且添加的新“汽车”可以采用最新颜色列表中的任何颜色。此外,您通常希望这个更新的颜色列表在程序重新启动后仍然有效。

To answer your question, it turns out that if you have a requirement for data constraint that can change at run-time, and those changes must survive a program restart, foreign keys are the simplest and most concise solution to the problem. The development cost is the addition of one table (e.g. "colours", a foreign key constraint to the "cars" table, and an index), and the run-time cost is the extra table lookup for the up-to-date colours to validate the data, and this run-time cost is usually mitigated by indexing and caching.

如果您不使用外键来满足这些需求,那么您必须编写软件来管理列表、查找有效的条目、将其保存到磁盘、如果列表很大的话有效地组织数据、确保对列表的任何更新都不会破坏列表文件、在有多个读取器和/或写入器的情况下提供对列表的串行访问,等等。例如,你需要实现大量的RDBMS功能。

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!

谢谢大家!