代码之家  ›  专栏  ›  技术社区  ›  NawaMan

何时使用“更新级联”

  •  366
  • NawaMan  · 技术社区  · 15 年前

    我经常使用“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 将被自动删除。这应该没问题。

    1. 这意味着“on update cascade”在 身份证件 父项的更新?

    2. 如果(1)为真,则表示在以下情况下无需使用“on update cascade” parent.id 不可更新(或永远不会更新),就像 AUTO_INCREMENT 或者总是被设定为 TIMESTAMP . 对吗?

    3. 如果(2)不是真的,在什么情况下我们应该使用“on update cascade”?

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

    好的,我知道,上面的一些问题可以通过测试程序来理解,但我也想知道这是否是数据库供应商的依赖。

    请放些光。

    6 回复  |  直到 8 年前
        1
  •  413
  •   Gray droiddeveloper    8 年前

    如果您的主键只是一个自动递增的标识值,那么您将不会真正使用on update cascade。

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

    在引用4时,如果将子ID更改为父表中不存在的内容(并且具有引用完整性),则应该会出现外键错误。

        2
  •  74
  •   Gray droiddeveloper    8 年前
    1. 是的,这意味着,例如 UPDATE parent SET id = 20 WHERE id = 10 所有10个孩子的家长ID也将更新为20

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

    3. 想不出还有别的用途。

    4. 当外键约束失败时,您不能这么做。

        3
  •  26
  •   Josh Davis    14 年前

    我想你已经把重点都搞定了!

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

    泽德 很有道理,如果你用 自然的 key(例如数据库表中的一个常规字段)作为主键,在某些情况下可能需要更新主键。最近的另一个例子是ISBN(国际标准书号),不久前,它从10位改为13位+字符。

    如果你选择使用 代理 (例如,人工系统生成的)密钥作为您的主键(这将是除了极少数情况之外的所有情况下我的首选)。

    所以最后:如果您的主键从未更改,那么您永远不需要 更新级联 条款。

    马克

        4
  •  14
  •   Ariel Grabijas    11 年前

    几天前我遇到了触发器的问题 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
    );
    

    在我的问题中,我必须定义一些额外的操作(触发器)来更新concert的表。这些操作必须修改俱乐部名称和乐队名称。因为引用,我做不到。我不能修改音乐会,然后处理俱乐部和乐队的桌子。我也不能用另一种方法。 更新级联 是解决这个问题的关键。

        5
  •  4
  •   ted.strauss    12 年前

    我的评论主要是指第3点:如果我们假设父密钥不可更新,那么在什么情况下可以使用update cascade?这是一个案子。

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

        6
  •  3
  •   nobody    10 年前

    这是个很好的问题,我昨天也有同样的问题。我考虑过这个问题,特别是搜索是否存在类似“on update cascade”的内容,幸运的是sql的设计者也考虑过这个问题。我同意特德·施特劳斯的观点,我也评论了诺兰的案子。

    我什么时候用的?正如Ted指出的,当你一次处理几个数据库时,其中一个表中的一个修改,在Ted所谓的“卫星数据库”中有任何一种复制,不能用非常原始的ID保存,并且由于任何原因,你必须创建一个新的ID。万一你不能更新旧的数据(例如,由于权限,或者如果你在快速的情况下搜索牢度,那就不值得绝对和完全尊重正常化的规则,仅仅因为它是一个非常短命的工具)。

    所以,我同意两点:

    (a)是的,在很多时候,更好的设计可以避免它;

    (b)在迁移、复制数据库或解决紧急情况的情况下,幸好当我去搜索它是否存在时,它是一个伟大的工具。