跨3个表的MySQL外键“ON DELETE CASCADE”

时间:2012-01-16 10:10:00

标签: mysql foreign-keys

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

  • 表格“分子”,列id
  • 表“描述符”,列“id”和“molecule_id”以及引用“molecule.id”的外键
  • 表“tDepDescriptor”,列“id”和“descriptor_id”以及引用“descriptor.id”的外键

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:4)

拥有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 |
+----+---------------+

答案 1 :(得分:0)

请确保您在使用更新/删除级联的外键中的所有其他表中使用Engine InnoDB,您可以使用:

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

我的经验:

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

(优先级)1​​米(包)1米(标准)

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