何时使用“ON UPDATE CASCADE”

我经常使用“ON DELETE CASCADE”,但是我从不使用“ON UPDATE CASCADE”,因为我不太确定它在什么情况下会有用。

为了讨论起见,请看一些代码。

CREATE TABLE parent ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ); CREATE TABLE child ( id INT NOT NULL AUTO_INCREMENT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ); 

对于“ON DELETE CASCADE”,如果删除了具有id的父项,则具有parent_id = parent.id子项中的logging将被自动删除。 这应该没问题。

  1. 这意味着“ON UPDATE CASCADE”会在更新父代的id时做同样的事情?

  2. 如果(1)为真,则意味着如果parent.id不可更新(或将永远不会更新),则不需要使用“ON UPDATE CASCADE”,就像它是AUTO_INCREMENT或始终设置为TIMESTAMP 。 是对的吗?

  3. 如果(2)不正确,我们还应该使用“ON UPDATE CASCADE”的其他情况?

  4. 如果我(由于某种原因)更新child.parent_id是不存在的东西,它会被自动删除?

那么,我知道,上面的一些问题可以编程testing来了解,但我也想知道这是否是数据库供应商依赖或不。

请说明一下。

确实,如果你的主键只是一个自动递增的标识值,那么对于ON UPDATE CASCADE就没有什么实际用处。

但是,假设您的主键是一个10位的UPC条形码,并且由于扩展,您需要将其更改为一个13位的UPC条形码。 在这种情况下,ON UPDATE CASCADE将允许您更改主键值,并且具有对该值的外键引用的任何表都将相应地进行更改。

在引用#4时,如果将子标识更改为父表中不存在的东西(并且具有参照完整性),则应该得到一个外键错误。

  1. 是的,这意味着,例如,如果你做UPDATE parent SET id = 20 WHERE id = 10所有儿童parent_id的10也将更新为20

  2. 如果您不更新外键所指的字段,则不需要此设置

  3. 想不到任何其他用途。

  4. 你不能这样做,因为外键约束将失败。

我认为你已经非常注意了点!

如果你遵循数据库devise的最佳实践,并且你的主键永远不可更新(我认为这应该永远是这种情况),那么你永远不需要ON UPDATE CASCADE子句。

Zed提出了一个很好的观点,即如果您使用自然键(例如数据库表中的常规字段)作为主键,那么在某些情况下您可能需要更新主键。 最近的另一个例子是国际标准书号(International Standard Book Numbers),它在不久之前从10位变成了13位数字+字符。

如果您select使用代理 (例如人造系统生成的)键作为主键(除了最罕见的情况之外,这将是我的首选),情况并非如此。

所以最后:如果你的主键从不改变,那么你永远不需要ON UPDATE CASCADE子句。

渣子

几天前我遇到了一个触发器问题,我发现ON UPDATE CASCADE可能是有用的。 看看这个例子(PostgreSQL):

 CREATE TABLE club ( key SERIAL PRIMARY KEY, name TEXT UNIQUE ); CREATE TABLE band ( key SERIAL PRIMARY KEY, name TEXT UNIQUE ); CREATE TABLE concert ( key SERIAL PRIMARY KEY, club_name TEXT REFERENCES club(name) ON UPDATE CASCADE, band_name TEXT REFERENCES band(name) ON UPDATE CASCADE, concert_date DATE ); 

在我的问题,我不得不定义一些额外的操作(触发)更新音乐会的表。 这些操作必须修改club_name和band_name。 由于参考,我无法做到。 我不能修改音乐会,然后处理俱乐部和乐队表。 我也不能这样做。 ON UPDATE CASCADE是解决问题的关键。

我的意见主要是参考第3点:在什么情况下ON UPDATE CASCADE适用,如果我们假设父键不可更新? 这是一个案例。

我正在处理复制scheme,其中多个卫星数据库需要与主站合并。 每颗卫星都在相同的表格上生成数据,所以将这些表格合并到主表格会导致违反唯一性约束。 我试图使用ON UPDATE CASCADE作为解决scheme的一部分,我在每次合并期间重新递增键。 在更新级联应该通过自动化部分过程来简化这个过程。

这是一个很好的问题,我昨天也有同样的问题。 我想到了这个问题,特别是如果存在像“ON UPDATE CASCADE”这样的问题,幸运的是SQL的devise者也想到了这个问题。 我同意Ted.strauss,而且我也评论了Noran的案例。

我什么时候用它? 像Ted指出的那样,当你一次处理好几个数据库时,其中之一的修改,在一张表中,在Ted所谓的“卫星数据库”中有任何一种复制,不能与原来保存的ID,出于任何原因,你必须创build一个新的,如果你不能更新旧的数据(例如,由于权限,或者如果你正在寻找坚固的情况下是如此短暂的不应该完全尊重正常化的总体规则,仅仅是因为它将是一个非常短暂的效用)

所以,我同意两点:

(答)是的,很多时候更好的devise可以避免它。 但

(B)在迁移,复制数据库或解决紧急事件的情况下,如果存在,那么幸运的是在那里进行search的时候是一个很棒的工具。