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 行....