Mat*_*nit 10 mysql database-design mysql-error-1451
这是我发生的事情的一个例子:
CREATE TABLE Parent (id BIGINT NOT NULL,
PRIMARY KEY (id)) ENGINE=InnoDB;
CREATE TABLE Child (id BIGINT NOT NULL,
parentid BIGINT NOT NULL,
PRIMARY KEY (id),
KEY (parentid),
CONSTRAINT fk_parent FOREIGN KEY (parentid) REFERENCES Parent (id) ON DELETE CASCADE) ENGINE=InnoDB;
CREATE TABLE Uncle (id BIGINT NOT NULL,
parentid BIGINT NOT NULL,
childid BIGINT NOT NULL,
PRIMARY KEY (id),
KEY (parentid),
KEY (childid),
CONSTRAINT fk_parent_u FOREIGN KEY (parentid) REFERENCES Parent (id) ON DELETE CASCADE,
CONSTRAINT fk_child FOREIGN KEY (childid) REFERENCES Child (id)) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)
请注意,Uncle-Child关系没有ON DELETE CASCADE; 即删除子项不会删除其叔叔,反之亦然.
当我有一个父母和一个叔叔同一个孩子,并且我删除了父母时,似乎 InnoDB应该能够"搞清楚"并让级联涟漪通过整个家庭(即删除父母删除叔叔)和孩子一样).但是,我得到以下内容:
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`cascade_test/uncle`, CONSTRAINT `fk_child` FOREIGN KEY (`childid`) REFERENCES `child` (`id`))
Run Code Online (Sandbox Code Playgroud)
InnoDB试图在引用它的叔叔之前级联删除Child.
我错过了什么吗?难道这应该失败由于某种原因,我不明白?或者是否有一些技巧使其工作(或者它是MySQL中的错误)?
在更简单的情况下,如果从Child删除记录并且它具有引用Uncle会发生什么?这是未指定的,因此无论如何约束都失败了.
如果删除子项不删除其Uncles,那么会发生什么?Uncle.childid不能为空.
你想要的是这三件事之一:
正如您所说,父删除正在触发子删除,我不知道为什么它会在叔叔表之前进入子表。我想您必须查看 dbms 代码才能确定,但我确信有一个算法可以选择首先级联到哪些表。
系统并没有真正按照您在这里暗示的方式“弄清楚”东西,它只是遵循其约束规则。问题是您创建的模式遇到了不允许它进一步通过的约束。
我明白你在说什么..如果它首先命中叔叔表,它将删除该记录,然后删除子项(并且不会从子项删除中命中叔叔级联)。但即便如此,我认为不会建立一个模式来依赖现实中的这种行为。我认为确定发生了什么的唯一方法是查看代码或让这里的 mysql/postgresql 程序员之一说明它如何处理 fk 约束。