MYSQL ON DELETE CASCADE - 仅在设置主键时有效
MYSQL ON DELETE CASCADE - Only works when set on a primary key
我在 MySQL 中遇到了 ON DELETE CASCADE
的问题。当它设置在 主键 字段上时,它工作得很好,但在其他情况下则不然。
例如,我有一个 child table,其中我有一个外键引用 parent table,但是 child table 有自己的 Auto-Incremental ID 字段需要作为主键,因为 grandchildren tables 引用它。
当我从 parent table 中删除一行时,所有记录都按预期消失并且没有出现错误,但是 child 的数据取决于删除的行parent table 保持不变。
我做了研究,没有结果。虽然我认为这与系统通过主键识别行有关,但我找不到任何相关信息。
parent table:
CREATE TABLE IF NOT EXISTS table_parent (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`level` TINYINT(1) NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
);
child table:
CREATE TABLE IF NOT EXISTS table_child (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
parentId TINYINT(3) UNSIGNED NOT NULL,
`name` VARCHAR(16) UNIQUE NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
);
关系:
ALTER TABLE table_child
ADD FOREIGN KEY (parentId) REFERENCES table_parent(ID) ON DELETE CASCADE
简而言之,我的目标是删除 table_child table 中的所有记录,其中 parentId 等于 table_parent 中删除的行。
感谢您的帮助,祝您有愉快的一天:)
在我看来,您缺少的是参照完整性约束仅适用于 InnoDB 表。您的 DDL 语句缺少 engine=InnoDB
并且很可能默认为 MyISAM。
虽然您不会在声明中收到错误消息,但默认情况下,MyISAM 表是您在未指定引擎时获得的表,并且 MyISAM 会忽略约束语句。
更正后的 CREATE TABLE 语句为:
CREATE TABLE IF NOT EXISTS table_parent (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`level` TINYINT(1) NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
) ENGINE=InnoDB;
Here's a SQL Sandbox 表明约束是正确的并且按您预期的方式工作。
这与问题无关,但您将所有密钥声明为 TINYINT 对我来说似乎很奇怪。这意味着您的表中最多可以有 255 行....
我在 MySQL 中遇到了 ON DELETE CASCADE
的问题。当它设置在 主键 字段上时,它工作得很好,但在其他情况下则不然。
例如,我有一个 child table,其中我有一个外键引用 parent table,但是 child table 有自己的 Auto-Incremental ID 字段需要作为主键,因为 grandchildren tables 引用它。
当我从 parent table 中删除一行时,所有记录都按预期消失并且没有出现错误,但是 child 的数据取决于删除的行parent table 保持不变。
我做了研究,没有结果。虽然我认为这与系统通过主键识别行有关,但我找不到任何相关信息。
parent table:
CREATE TABLE IF NOT EXISTS table_parent (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`level` TINYINT(1) NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
);
child table:
CREATE TABLE IF NOT EXISTS table_child (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
parentId TINYINT(3) UNSIGNED NOT NULL,
`name` VARCHAR(16) UNIQUE NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
);
关系:
ALTER TABLE table_child
ADD FOREIGN KEY (parentId) REFERENCES table_parent(ID) ON DELETE CASCADE
简而言之,我的目标是删除 table_child table 中的所有记录,其中 parentId 等于 table_parent 中删除的行。
感谢您的帮助,祝您有愉快的一天:)
在我看来,您缺少的是参照完整性约束仅适用于 InnoDB 表。您的 DDL 语句缺少 engine=InnoDB
并且很可能默认为 MyISAM。
虽然您不会在声明中收到错误消息,但默认情况下,MyISAM 表是您在未指定引擎时获得的表,并且 MyISAM 会忽略约束语句。
更正后的 CREATE TABLE 语句为:
CREATE TABLE IF NOT EXISTS table_parent (
ID TINYINT(3) UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`level` TINYINT(1) NOT NULL,
updated DATETIME NOT NULL DEFAULT NOW()
) ENGINE=InnoDB;
Here's a SQL Sandbox 表明约束是正确的并且按您预期的方式工作。
这与问题无关,但您将所有密钥声明为 TINYINT 对我来说似乎很奇怪。这意味着您的表中最多可以有 255 行....