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

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

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


当前回答

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

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

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

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

其他回答

没有充分的理由不使用它们……除非孤行对你来说不是什么大问题。

像许多事情一样,这是一种权衡。这是一个你想在哪里进行验证数据完整性的工作的问题:

(1)使用外键(单点配置为一个表,功能已经实现,经过测试,证明有效)

(2)把它留给数据库的用户(可能多个用户/应用程序更新同一个表),这意味着更多潜在的故障点和测试的复杂性)。

数据库执行(2)更有效,使用(1)更容易维护,风险更小。

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!

谢谢大家!

如果您绝对确信底层数据库系统将来不会改变,我将使用外键来确保数据完整性。

但在现实生活中,还有一个完全不使用外键的很好的理由:

您正在开发一个产品,该产品应该支持不同的数据库系统。

如果您正在使用实体框架(Entity Framework),该框架能够连接到许多不同的数据库系统,那么您可能还希望支持“开源免费”的无服务器数据库。并非所有这些数据库都支持外键规则(更新、删除行……)。

这会导致不同的问题:

1)。在创建或更新数据库结构时,可能会遇到错误。可能只有无声错误,因为数据库系统忽略了外键。

2)。如果依赖于外键,则可能在业务逻辑中较少甚至不进行数据完整性检查。现在,如果新的数据库系统不支持这些外键规则,或者只是以不同的方式运行,那么您必须重写业务逻辑。

您可能会问:谁需要不同的数据库系统?当然,不是每个人都能负担得起或想要在他的机器上安装一个完整的SQL-Server。这是软件,需要维护。其他人已经在其他一些DB系统上投入了时间和金钱。无服务器数据库非常适合只有一台机器上的小客户。

没有人知道,所有这些DB系统是如何运行的,但是您的业务逻辑,包括完整性检查,总是保持不变的。

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,但它的风险必须由程序员来处理。