何时使用“ ON UPDATE CASCADE”

淺唱寂寞╮ 提交于 2020-02-27 12:15:13

我经常使用“ 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具有parent_id = parent.id的记录。 这应该没问题。

  1. 这意味着,当父代的id更新时,“ ON UPDATE CASCADE”将执行相同的操作吗?

  2. 如果(1)为true,则意味着如果parent.id不可更新(或永远不会被更新)(如将其设置为AUTO_INCREMENT或始终设置为TIMESTAMP ),则无需使用“ ON UPDATE CASCADE”。 那正确吗?

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

  4. 如果我(出于某种原因)将child.parent_id更新为不存在的内容,然后将其自动删除怎么办?

好吧,我知道,上面的某些问题可以通过编程测试来理解,但我也想知道其中是否有任何数据库供应商依赖性。

请说明一下。


#1楼

我的评论主要是针对第3点:在什么情况下,如果我们假设父键不可更新,那么在什么情况下可以使用ON UPDATE CASCADE? 这是一种情况。

我正在处理一个复制方案,其中多个卫星数据库需要与一个主数据库合并。 每个卫星都在同一表上生成数据,因此将表合并到主表将导致违反唯一性约束。 我正在尝试使用ON UPDATE CASCADE作为解决方案的一部分,在该解决方案中,我会在每次合并期间重新增加键。 ON UPDATE CASCADE应该通过自动化部分过程来简化此过程。


#2楼

几天前,我遇到了触发器问题,并且我发现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不会真正使用。

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

关于#4,如果您将子ID更改为父表中不存在的某种东西(并且具有参照完整性),则应该得到外键错误。


#4楼

  1. 是的,这意味着,例如,如果您执行UPDATE parent SET id = 20 WHERE id = 10所有UPDATE parent SET id = 20 WHERE id = 10孩子的parent_id也会更新为20

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

  3. 想不到其他用途。

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


#5楼

我认为您已经确定了要点!

如果您遵循数据库设计的最佳实践,并且您的主键永远是不可更新的(无论如何我都应该总是这样),那么您根本就不需要ON UPDATE CASCADE子句。

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

如果您选择使用代理 (例如,由系统人工生成的) 替代键作为主键,则不是这种情况(这是我的首选,除了最罕见的情况)。

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!