【问题标题】:MySQL Foreign Key "ON DELETE CASCADE" across 3 tables跨 3 个表的 MySQL 外键“ON DELETE CASCADE”
【发布时间】:2012-02-11 07:15:18
【问题描述】:

我的数据库中有 3 个表(还有更多,但还没有与这些表的连接)

  • 具有列 ID 的表“分子”
  • 表“descriptor”,列“id”和“molecule_id”,外键引用“molecule.id”
  • 表“tDepDescriptor”,列“id”和“descriptor_id”,外键引用“descriptor.id”

(每个表都有更多列,但这些列都不是外键或类似的东西)

所有外键都指定了“on delete cascade”,所有 id 都是 unsigned int(5)。

现在,如果我尝试删除“分子”中的一个条目,该条目在“描述符”和“tDepDescriptor”中有引用条目,就像外键设置为“更新限制”一样,不会发生任何错误,不会给出错误. 如果我删除“descriptor”中的条目,“tDepDescriptor”中的所有引用条目都将被删除。 如果我尝试删除“分子”中的条目,在“描述符”中有引用条目,但没有引用“tDepDescriptor”中的那些“描述符”条目,也会发生同样的情况。 所以“on delete cascade”适用于两个表,但是当涉及三个表时,“cascade”似乎没有传递。

这些表应该做的是: 当我想删除“分子”中的条目时,“描述符”中的所有引用条目都将被删除。因此,“tDepDescriptor”中引用“descriptor”中已删除条目之一的所有条目也将被删除。

mysql服务器版本为5.1,引擎为InnoDB

希望有人能按照这个复杂的解释来帮助我。

//编辑: 发现了问题。 似乎是 phpMyAdmin 的问题,而不是数据库的问题。单击 PMA 中的删除不起作用,但手动编码查询确实,级联所有三个表。奇怪,但至少我知道我的桌子工作正常。

【问题讨论】:

    标签: mysql foreign-keys


    【解决方案1】:

    有 ON DELETE CASCADE 选项就足够了。看看这个例子:

    创建和填写表格:

    CREATE TABLE molecule (
      id INT(11) NOT NULL,
      PRIMARY KEY (id)
    )
    ENGINE = INNODB;
    
    CREATE TABLE descriptor (
      id INT(11) NOT NULL,
      molecule_id INT(11) DEFAULT NULL,
      PRIMARY KEY (id),
      CONSTRAINT FK_descriptor_molecule_id FOREIGN KEY (molecule_id)
        REFERENCES molecule(id) ON DELETE CASCADE ON UPDATE RESTRICT
    )
    ENGINE = INNODB;
    
    CREATE TABLE tdepdescriptor (
      id INT(11) NOT NULL,
      descriptor_id INT(11) DEFAULT NULL,
      PRIMARY KEY (id),
      CONSTRAINT FK_tdepdescriptor_descriptor_id FOREIGN KEY (descriptor_id)
        REFERENCES descriptor(id) ON DELETE CASCADE ON UPDATE RESTRICT
    )
    ENGINE = INNODB;
    
    INSERT INTO molecule VALUES 
      (1),
      (2),
      (3);
    
    INSERT INTO descriptor VALUES 
      (1, 1),
      (2, 1),
      (3, 2);
    
    INSERT INTO tdepdescriptor VALUES 
      (1, 1),
      (2, 2),
      (3, 3);
    

    删除一个分子及其所有描述符及其所有 tdepdescriptor:

    DELETE FROM molecule WHERE id = 1;
    
    SELECT * FROM molecule;
    +----+
    | id |
    +----+
    |  2 |
    |  3 |
    +----+
    
    SELECT * FROM descriptor;
    +----+-------------+
    | id | molecule_id |
    +----+-------------+
    |  3 |           2 |
    +----+-------------+
    
    SELECT * FROM tdepdescriptor;
    +----+---------------+
    | id | descriptor_id |
    +----+---------------+
    |  3 |             3 |
    +----+---------------+
    

    【讨论】:

      【解决方案2】:

      请确保您在所有链接的表中使用 Engine InnoDB,以便在更新/删除级联时在外键中互相观察,您可以使用:

      create table test1 (
        #column definitions, including fk with on delete/update cascade
      ) engine = "InnoDB";
      

      我的经验:

      我在我的一个项目中遇到了同样的问题。给了我一个已经开发好的数据库来添加更多的部分。这些表在外键上没有删除/更新级联。我添加了它们,还从 cPanel 的 phpMyAdmin 的“查询”选项卡中添加了另一个表。所以我的关系是:

      (优先级)1​​-m(包)1-m(标准)

      全部带有删除/更新级联。但是当我以前删除“优先级”时,“标准”没有被删除。 “InnoDB”引擎存在“priorities”和“packages”,当我创建“standards”表时,我没有指定ENGINE,所以它默认使用“MyISAM”,这导致了问题。当我使用明确提到的 ENGINE="InnoDB" 重新创建表时,问题就解决了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-06
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        • 2021-03-29
        相关资源
        最近更新 更多