设立时,外键在SQL服务器上,应在何种情况下你拥有这一级上删除或更新,是什么原因呢?

这可能适用于其他数据库。

我在找一大部分的所有具体示例中的每一个方案中,优从某人具有使用它们成功。

有帮助吗?

解决方案

摘要什么我已经看到迄今为止:

  • 有些人不喜欢叠。

联级删除

  • 联级删除可能会使意义上当的语义关系可能涉及一个独家的 "是一部分"描述。例如,一个OrderLine记录的一部分,其父母顺序,并OrderLines将永远不会之间共享的多个订单。如果以要消失,OrderLine应该作为良好,并没有一个顺序将是一个问题。
  • 的典型例子,对级联删除是SomeObject和SomeObjectItems,在那里没有任何意义的一项记录永远存在没有相应的主要记录。
  • 你应该 使用级联删除如果你是保存历史记录或使用一个"软性/逻辑删除"在那里你只设一个被删除的位列1/true。

联级更新

  • 联级更新可能是有意义的时候你使用一个真正的钥匙,而不是一种替代的关键(身份的/自动增量列)在表。
  • 典型的例级更新是当你有一个可变的外键的,就像一个用户名,可以改变的。
  • 你应该 使用联级更新的钥匙,是身份/自动增量列。
  • 联级更新是最好的结合使用一个独特的约束。

当使用联

  • 你可能想要获得额外的强大的确认回从前用户允许的操作级联,但它取决于应用程序。
  • 联可以让你陷入麻烦,如果你设置外键错误的。但你应该好吧如果你这样做的权利。
  • 这是不明智的使用级联之前你了解它彻底。然而,它是一个有用的特征,并因此值得考虑的时间来理解。

其他提示

外键是最好的方式,确保引用完整性的一个数据库。避免了瀑布,由于被魔法是喜欢写作中的一切都会因为你不相信魔法背后编译器。

什么是坏是错误的使用外键的,就像他们创造倒退,例如。

胡安*曼努埃尔的例子是规范的例子,如果使用代码还有更多的机会离开寄生DocumentItems在数据库,该数据库将来咬你。

联级的更新都是有用的,例如,当你提到的数据通过一些可以改变,说一个主要关键的一个用户表的姓名、姓氏组合。然后你想要的变化,组合传播到,无论他们身在何处引用。

@艾丹,这清楚你指的是在一个高成本的机会而留下虚假的数据,在你的数据库,该数据库 不小.对我来说,这是通常只是缺乏熟悉该数据库以及无法找到其驻在的地方工作之前,与数据库,促进这种恐惧。要么,或常滥用的级,使用它在那里的实体都没有概念相关,或者在那里你必须保护历史。

我从来没有使用联删除。

如果我想要的东西从数据库中删除,我要明确告诉数据库什么我想要取出。

当然他们是一个功能提供数据库和可能有时候它是好的使用,例如如果你有一个"秩序"表和一个'orderItem'表你可能想要清除的项目时,你删除的顺序。

我喜欢清楚起见,我得到这样做在代码(或存储的过程),而不是"神奇"事情的发生。

出于同样的原因,我的触发器。

东西要注意的是,如果你做删除"订单"中,你将得到1个行受影响的报告后,即使级联删除已除去50'orderItem。

我工作了很多与联删除。

这感觉很好要知道谁作对该数据库可能永远不会离开任何不必要的数据。如果增长的依赖关系,我只是改变的制约因素diagramm在管理工作室和我没必要调整sp或dataacces.

这就是说,我有1的问题与联删除,这就是圆形的参考。这往往导致零部件的数据库没有联删除。

我做了很多数据库的工作,并很少能找到级联删除有用的。这一次我使用了他们有效地是在报告数据库进行更新,通过夜间工作。我确信,任何改变的数据导入正确,删除任何顶级的记录有改变,因为最后一个进口、然后重新进口的修改的记录以及任何涉及他们。它救了我从具有编写大量的复杂删除,从下到上的我的数据库。

我不考虑级联删除是相当糟糕,因为触发因为它们只删除的数据,触发可以拥有所有种讨厌的东西里面。

总的来说,我避免的现实完全删除,并使用逻辑删除(ie。有一点列称在被删除,获取设置为真正)代替。

一个例子是,当你必须依赖关系的实体之间的...即:文->DocumentItems(当删除的文件,DocumentItems没有存在的理由)

使用级联删除那里你会想要的记录与FK被删除,其参照PK记录被删除。换句话说,这里的记录是没有意义的引用记录。

我找到级联删除用来确保死的参考文献被删除,通过默认,而不是导致空例外情况。

上删除级联:

当你想要的 行儿童表将被删除 如果 相应的行被删除 在父母表。

如果 在级联中删除 不用然后一个错误将被提出 引用完整性.

在更新联级:

当你想要的 改变主键 更新 外键

其中一个原因把一级联删除(而不是这样做的代码),以改善性能。

案例1:一级联删除

 DELETE FROM table WHERE SomeDate < 7 years ago;

案例2:没有一级联删除

 FOR EACH R IN (SELECT FROM table WHERE SomeDate < 7 years ago) LOOP
   DELETE FROM ChildTable WHERE tableId = R.tableId;
   DELETE FROM table WHERE tableId = R.tableid;
   /* More child tables here */
 NEXT

其次,在添加一个额外的儿童表一级联删除,代码于1的情况下保持工作。

我只会把在瀑布那里的语义关系是"一部分"。否则一些白痴将删除一半的数据库当你这样做:

DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'

我已经听到数据库管理员和/或"公司的政策",禁止使用"上删除瀑布"(和其他)纯粹是因为不良的经验,在过去。在一种情况下一个人写了三个触发器,它结束了一个另一个。三天的恢复导致全面禁止触发器,因为所有的行动的一个idjit.

当然有时触发的需要,而不是"上删除瀑布",如当一些儿童的数据需要保护。但在其他情况下,它完全有效的使用上删除级联的方法。一个关键的优势"在删除瀑布",它抓住所有的儿童;一个自定义的书面触发器/储存过程可能不如果是编码不正确。

我相信开发人员应当允许作出决定依据什么发展是和什么样的规格说。地毯禁止基于一个糟糕的经历不应该标准;"永远不会使用"的思维过程是严厉的。一个判断需要作出的每一次和所作的改变为业务模式的变化。

这不是什么发展是所有有关吗?

我尽量避免删除或更新,我没有明确要求在SQL服务器。

通过级联或通过使用的触发器。他们往往咬你的屁股一段时间的路线,无论是在试图追踪一个错误,或者当诊断性能的问题。

在那里我会用他们在确保一致性没有很多的努力。获得同样的效果你就必须利用存储程序。

我和其他人一样在这里,发现级联删除真的只是略有帮助(这真的不是很多工作,以删除引用的数据在其他表--如果有很多的表格,你只是自动执行这一脚本)但是真的很讨厌当有人意外地级联删除一些重要的数据,难以恢复。

唯一的情况下,我使用的是,如果表格中的数据表是高度控制(例如,有限的权限)和唯一的更新的或从中删除,通过一个控制程序(如软件更新),已被验证。

删除或更新至S,将删除一个外国的关键价值的发现在一些组R能够处理在三个方面:

  1. 拒绝
  2. 传播
  3. 废除.

传播中被称为层叠。

有两种情况:

秀,如果一个多元组在S删除,删除R元组提到它。

秀,如果一个多元组在S进行了更新,更新值R元组提到它。

如果你在工作上的一个系统有很多不同的模块不同的版本,它可以是非常有用的,如果对级联删除项目的一部分/所有的PK架。还有,所有模块将需要立即修补清理他们的依赖性的项目之前,删除PK所有者或该外国的关键关系将是完全省略,可能离开吨垃圾中的系统如果清理是不正确地执行。

我刚才介绍级联删除一个新的交点表之间的两个已经存在的表(交叉路口仅删除),之后的级联删除已被劝阻不要相当长的一段时间。它也不会太糟糕,如果数据丢失。

然而,它是一个糟糕的事情在枚举样的列表格:有人删除项13-黄表"色彩",以及所有黄色的项目在数据库中被删除。此外,这些有时得到更新,删除所有入所有的方式,导致参照完整性完全省略。这当然是错误的,但是你将如何改变一个复杂的软件,该软件已运行多年,有的介绍的真正的参照完整性是危险的意外副作用吗?

另一个问题是,当原来的外键值应保持甚至后的主要关键已被删除。一个可以创建一个墓碑柱上删除置空选择的原FK,但这再次需要触发器或特定代码的维持冗余的(除非后PK删除)关键的价值。

联级删除的极为有用的当实现逻辑上的超级种类和子类型的实体物理数据库。

当单独超级种类和子类型表是用于物理实施超类/子类型(而不是滚动的所有子类型的属性成一个单一的身体超类型表格),有一个一对一的关系,这些表格和问题,然后变得如何保持主键100%之间的同步,这些表格。

级联删除可能是一个非常有用的工具:

1)确保删除一个超级类型的记录也删除相应的单个子类型的记录。

2)确保任何删除的一个子类型的记录也将删除超类型的记录。这是通过实施"而不是"删除触发的分类表,并删除相应的超级类型的记录,而这又级联删除该子类型的记录。

使用级联删除以这种方式确保没有孤儿的超级式或分式记录永远存在,不管你是否删除该超类型记录的第一个或子类型记录的第一个。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top