【问题标题】:MySQL foreign key on same table同一张表上的MySQL外键
【发布时间】:2013-08-28 04:32:14
【问题描述】:

我有一张存储 cmets 的表。每条评论都有自己的 ID 和 isReply 列,以防评论是对另一条评论的回复。我想知道是否可以设置一个关系,以便在删除评论时自动删除所有回复该评论的 cmets。我尝试为引用comments.idisReply 列设置外键,但出现此错误:

#1452 - 无法添加或更新子行:外键约束失败(_db.#sql-1030_31f,CONSTRAINT #sql-1030_31f_ibfk_1 外键 (isReply) 引用 comments (id) 删除级联 更新无操作)

【问题讨论】:

  • 你能做一个显示上述错误的简化sqlfiddle吗?顺便说一句,不要忘记这个限制:dev.mysql.com/doc/refman/5.0/en/… 另一方面,自引用 ON DELETE SET NULL 是可能的,就像自引用 ON DELETE CASCADE 一样。级联操作的嵌套深度不得超过 15 级。
  • DELETE c1 FROM comments c1 LEFT JOIN comments c2 ON c2.id=c1.isReply WHERE c2.id IS NULL。这应该会删除对已删除 cmets 的所有回复。然后添加一个 FK 就可以了。而不是删除一个可以替代UPDATE ... LEFT JOIN ... ON ... SET c1.isReply=NULL WHERE ...

标签: mysql


【解决方案1】:

您的 cmets 表可能仍有答案,其中 isReply 值引用了在您的测试期间已删除的 cmets。听听 MySQL 想说什么:

a foreign key constraint fails

您所要做的就是清空表,定义外键(您的错误应该消失),然后您将获得所需的行为。创建 FK 后,无需触发器,这就是级联存在的原因。

注意,您可能希望使用以下命令将 isReply 的默认值设置为 null

ALTER TABLE comments CHANGE isReply isReply integer DEFAULT NULL;

【讨论】:

  • 好吧,您已经对这种情况有所了解。我清空了整个表并成功添加了密钥,但是当我现在尝试添加记录时,我得到Cannot add or update a child row: a foreign key constraint fails (_db.cmets, CONSTRAINT opinions_ibfk_1` FOREIGN KEY (isReply) REFERENCES comments (id ) ON DELETE CASCADE ON UPDATE NO ACTION)`
  • @php_nub_qq 你应该先添加 cmets,然后然后回答。它不会反过来工作。尝试插入一条评论,然后插入一个答案。使用表中的选择进行调试,以确保引用的父级存在。
  • 我正在插入评论,而不是回复评论。这是奇怪还是什么?
  • @php_nub_qq 啊,当然,你也应该在FK栏(isReply)上允许null。见this post
  • 正如@edsioufi 所说和@biziclop 指出的那样。 isReply 应该可以为空并且默认为 NULL。另外我建议你也将ON UPDATE 设置为CASCADE
【解决方案2】:

实际上,同一张表中的外键完全有效的。 1452 仅表示您有一个或多个项目引用了一个不存在(不再存在)的项目,因此根据您的外键定义无效。

有关更多信息,请参阅:Mysql error 1452 - Cannot add or update a child row: a foreign key constraint fails 它解释了失败的原因、如何找到失败的记录以及如何规避问题。

【讨论】:

  • 你在说我的儿子:]
【解决方案3】:

创建一个触发器来删除所有具有相同条件的记录。当在 cmets 表中删除一条记录时。

Check triggers documentation

看看this Question

否则,你不能使用在同一个表中的列作为外键。

【讨论】:

  • 但是如果我创建了一个触发器,在整个数据库的导出和导入的情况下它是否仍然存在:/
  • 如果您将删除评论关联到删除回复的查询,它们将从数据库中删除,因此无法导出,如果您想将它们存储在数据库中,请尝试在您的数据库中添加布尔字段“isDeleted”表并将其值从 false 更改为 true
猜你喜欢
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多