在SQL Server中设置外键时,在什么情况下应该在删除或更新时级联它,背后的原因是什么?
这可能也适用于其他数据库.
我最关注每个场景的具体例子,最好是那些成功使用它们的人.
到目前为止我所看到的摘要:
有些人根本不喜欢级联.
当关系的语义可能涉及排他性"属于 "描述时,级联删除可能是有意义的.例如,OrderLine记录是其父订单的一部分,OrderLines永远不会在多个订单之间共享.如果订单消失,OrderLine也应如此,没有订单的行将是一个问题.
Cascade Delete的规范示例是SomeObject和SomeObjectItems,在没有相应主记录的情况下,项目记录永远不会有任何意义.
你应该不使用级联删除,如果你保存历史或使用"软/逻辑删除",您只设置一个删除位列1 /真.
当您在表中使用真实密钥而不是代理键(标识/自动增量列)时,级联更新可能有意义.
Cascade Update的典型示例是当您有可变外键时,例如可以更改的用户名.
你应该不使用级联更新与被标识/自动增量列键.
级联更新最好与唯一约束一起使用.
在允许级联操作之前,您可能希望从用户那里获得额外的强确认,但这取决于您的应用程序.
如果您设置了错误的外键,级联可能会让您遇到麻烦.但如果你这样做,你应该没问题.
在彻底理解之前使用级联是不明智的.但是,它是一个有用的功能,因此值得花时间去理解.
外键是确保数据库参照完整性的最佳方法.避免由于神奇而导致的级联就像在汇编中编写所有内容一样,因为你不相信编译器背后的魔力.
例如,错误使用外键,例如向后创建它们是坏事.
Juan Manuel的示例是规范示例,如果您使用代码,则会有更多机会将虚假的DocumentItems留在数据库中,这会让您感到困惑.
例如,当您通过可以更改的内容引用数据时,级联更新很有用,例如,用户表的主键是名称,姓氏组合.然后,您希望该组合中的更改传播到引用它们的任何位置.
@Aidan,你提到的清晰度是高成本的,在你的数据库中留下虚假数据的可能性很小.对我来说,通常只是缺乏对数据库的熟悉,并且无法在使用能够助长恐惧的数据库之前找到哪些FK.要么是,要么不断地滥用级联,在实体没有概念相关的情况下使用它,或者你必须保存历史.
我从不使用级联删除.
如果我想从数据库中删除一些东西,我想明确告诉数据库我想要取出什么.
当然它们是数据库中可用的功能,有时可以使用它们,例如,如果你有一个'order'表和'orderItem'表,你可能想删除一个项目时清除项目订购.
我喜欢在代码(或存储过程)中使用它而不是"魔术"发生的清晰度.
出于同样的原因,我也不是触发器的粉丝.
需要注意的是,如果您确实删除了"订单",即使级联删除已删除了50个"orderItem",您也会收到"1行受影响"报告.
我通过级联删除工作了很多.
知道对数据库起作用的人可能永远不会留下任何不需要的数据.如果依赖关系增长,我只需更改Management Studio中diagramm中的约束,我就不必调整sp或dataacces.
也就是说,我有1个级联删除问题,那就是循环引用.这通常会导致数据库中没有级联删除的部分.
我做了很多数据库工作,很少发现级联删除有用.有一次我有效地使用它们是在报告数据库中,由夜间工作更新.通过删除自上次导入以来已更改的任何顶级记录,然后重新导入已修改的记录以及与其相关的任何内容,我确保正确导入任何已更改的数据.它使我不必编写大量从数据库的底部到顶部的复杂删除.
我不认为级联删除与触发器一样糟糕,因为它们只删除数据,触发器内部可能有各种令人讨厌的东西.
一般来说,我完全避免使用真正的Deletes并使用逻辑删除(即,将一个名为isDeleted的位列设置为true).
一个例子是当你有实体之间的依赖关系时...即:Document - > DocumentItems(当你删除Document时,DocumentItems没有理由存在)
使用级联删除,如果删除了引用的PK记录,则需要删除带有FK的记录.换句话说,如果没有引用记录,记录就毫无意义.
我发现级联删除有用,以确保默认情况下删除死引用,而不是导致空异常.
想要删除子表中的行时如果在父表中删除了相应的行。
如果不使用级联删除,则会导致参照完整性的错误。
当您想更改主键中的外键中的更新