我记得在播客014中听到Joel Spolsky提到他几乎从未使用过外键(如果我没记错的话)。然而,对我来说,它们对于避免数据库中的重复和后续数据完整性问题非常重要。
人们是否有一些可靠的理由(以避免与Stack Overflow原则一致的讨论)?
编辑:“我还没有创建外键的理由,所以这可能是我真正建立一个外键的第一个理由。”
我记得在播客014中听到Joel Spolsky提到他几乎从未使用过外键(如果我没记错的话)。然而,对我来说,它们对于避免数据库中的重复和后续数据完整性问题非常重要。
人们是否有一些可靠的理由(以避免与Stack Overflow原则一致的讨论)?
编辑:“我还没有创建外键的理由,所以这可能是我真正建立一个外键的第一个理由。”
当前回答
“它们会使删除记录变得更加麻烦——你不能删除“主”记录,而其他表中的记录中有外键会违反这种约束。”
重要的是要记住,SQL标准定义了删除或更新外键时所采取的操作。 我所知道的是:
ON DELETE RESTRICT - Prevents any rows in the other table that have keys in this column from being deleted. This is what Ken Ray described above. ON DELETE CASCADE - If a row in the other table is deleted, delete any rows in this table that reference it. ON DELETE SET DEFAULT - If a row in the other table is deleted, set any foreign keys referencing it to the column's default. ON DELETE SET NULL - If a row in the other table is deleted, set any foreign keys referencing it in this table to null. ON DELETE NO ACTION - This foreign key only marks that it is a foreign key; namely for use in OR mappers.
这些相同的操作也适用于ON UPDATE。
默认值似乎取决于您使用的sql server。
其他回答
我只知道Oracle数据库,不知道其他数据库,而且我知道外键对于保持数据完整性是必不可少的。在插入数据之前,需要建立一个数据结构,并且建立正确的数据结构。当这一步完成时——所有的主键和外键都创建好了——工作就完成了!
意思是:孤立的行?不。这辈子都没见过。除非一个糟糕的程序员忘记了外键,或者他在另一个层次上实现了外键。在Oracle的环境中,这两者都是巨大的错误,会导致数据复制、孤儿数据,从而导致数据损坏。我无法想象一个没有强制FK的数据库。在我看来是一片混乱。这有点像Unix权限系统:假设每个人都是root用户。想想混乱吧。
外键是必不可少的,就像主键一样。这就像是说:如果我们移除主键会怎样?那么,整个混乱将会发生。这是什么。不能将主键或外键的职责移到编程级别,但必须移到数据级别。
缺点呢?是的,当然!因为在插入时,会有更多的检查。但是,如果数据完整性比性能更重要,那么这是显而易见的。Oracle上的性能问题更多地与索引有关,索引包含PK和FK。
我同意德米特里的话,但要补充一点。
我在一个批处理计费系统中工作,需要在30多个表中插入大量的行。我们不允许做数据泵(Oracle),所以我们必须做批量插入。这些表上有外键,但我们已经确保它们不会破坏任何关系。
在插入之前,我们禁用外键约束,这样Oracle就不会一直进行插入。插入成功后,我们重新启用约束。
PS:在一个大型数据库中,一条记录有许多外键和子行数据,有时外键可能不好,您可能希望禁止级联删除。对于在计费系统中的我们来说,如果进行级联删除,将花费太长时间,并且对数据库造成太大负担,因此我们只是在主驱动程序(父)表上使用一个字段将记录标记为坏记录。
验证外键约束需要一些CPU时间,因此有些人省略外键以获得额外的性能。
@ emphasis——这正是导致维护噩梦的心态。
为什么,哦,为什么要忽略声明性引用完整性(其中数据至少可以保证一致),而支持所谓的“软件强制”,这充其量是一种薄弱的预防措施。
我不得不在这里第二多的评论,外键是必要的项目,以确保你有完整的数据。ON DELETE和ON UPDATE的不同选项将允许你绕过一些人们在这里提到的关于它们的使用的“下降”。
我发现在我99%的项目中,我会使用FK来加强数据的完整性,然而,在很少的情况下,我的客户必须保留他们的旧数据,不管它有多糟糕....但后来我花了很多时间写代码,只得到有效的数据,所以它变得毫无意义。