【问题标题】:Can't drop table: A foreign key constraint fails无法删除表:外键约束失败
【发布时间】:2012-06-21 11:44:14
【问题描述】:

在 MySQL 中,我想删除一个表。
我尝试了很多东西,但我不断收到名为 bericht 的表无法删除的错误。这是我得到的错误:

#1217 - 无法删除或更新父行:外键约束失败

如何删除此表?

【问题讨论】:

标签: mysql sql drop-table


【解决方案1】:

使用show create table tbl_name查看外键

您可以使用此语法删除外键:

ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol

这里还有更多信息(请参阅 Frank Vanderhallen 的帖子): http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT * 
    FROM information_schema.KEY_COLUMN_USAGE 
    WHERE REFERENCED_TABLE_NAME = 'YourTable';
    

    这应该会向您提供哪些表引用了您要删除的表,一旦您删除这些引用,或者引用此表中数据集的数据集,您将能够删除该表

    【讨论】:

    • 最好的方式来查看 fks 而不强制删除可能会产生不希望的结果。
    • 破解外键检查通常是个坏主意(由于不可预见的连锁效应)。 这个是正确的方法。
    【解决方案3】:

    这应该可以解决问题:

    SET FOREIGN_KEY_CHECKS=0; DROP TABLE bericht; SET FOREIGN_KEY_CHECKS=1;
    

    正如其他人指出的那样,这几乎从来都不是您想要的,即使它是问题中所要求的。更安全的解决方案是在删除bericht 之前删除依赖于bericht 的表。有关如何做到这一点,请参阅 CloudyMarble 答案。当我不想或无法删除并重新创建数据库本身时,我会使用 bash 和帖子中的方法删除数据库中的所有表。

    #1217 错误发生在其他表对您尝试删除的表具有外键约束并且您正在使用 InnoDB 数据库引擎时。此解决方案暂时禁用检查约束,然后重新启用它们。阅读documentation 了解更多信息。请务必根据bericht 删除表中的外键限制和字段,否则您的数据库可能会处于损坏状态。

    【讨论】:

    • 虽然它是正确的,但这样做是一个非常糟糕的做法。正如多位用户(包括 Rune Kaagaard)所指出的,您应该找到参考资料,根据需要进行分析和删除。
    • 在删除表然后再次创建它的情况下(可能进行了一些更改,但 FK 列仍然存在),那么这是一个很好的解决方案。再次创建表后,其他表中的外键仍然有效。另外:可以改为修改表而不是 DROP 然后 CREATE - 这可能是更正确的解决方案。但是,如果使用脚本创建表,我认为想要使用 DROP / CREATE 方法是明智的。
    • 我遇到过没有表引用我试图删除的表的情况,但出现了同样的错误。 select * from information_schema.KEY_COLUMN_USAGE where referenced_table_name = 'table_to_delete'; 返回一个空集。我认为这是 InnoDB 引擎的问题。这个解决方案也适用于我的情况。
    • 这可能是最好的答案。我有一个情况,两个表都有相互的外键引用。两者都不允许在另一个之前被丢弃。所以关闭外键检查是有道理的。我只需要在开发阶段而不是在生产阶段这样做。
    • 人们说这是不好的做法,但这确实取决于用例,所以不要无缘无故地使用大词......
    【解决方案4】:

    这可能与其他架构具有相同的表,这就是您收到该错误的原因。

    您需要先删除子行,然后删除父行。

    【讨论】:

    • 您能进一步解释一下吗?怎么能找到那个“父行”?
    【解决方案5】:

    我意识到这已经过时并且已经选择了一个答案,但是允许外键为 NULL 然后选择 的替代方法怎么样>ON DELETE SET NULL.

    基本上,你的表应该这样改变:

    ALTER TABLE 'bericht' DROP FOREIGN KEY 'your_foreign_key';

    ALTER TABLE 'bericht' ADD CONSTRAINT 'your_foreign_key' FOREIGN KEY ('column_foreign_key') REFERENCES 'other_table' ('column_parent_key') ON UPDATE CASCADE ON DELETE SET NULL;

    我个人建议同时使用“ON UPDATE CASCADE”和“ON DELETE SET NULL”来避免不必要的并发症,但是您的设置可能需要不同的方法。

    希望这会有所帮助。

    【讨论】:

      【解决方案6】:

      但幸运的是,使用 MySQL FOREIGN_KEY_CHECKS 变量,您根本不必担心 DROP TABLE 语句的顺序,您可以按照自己喜欢的任何顺序编写它们——甚至完全相反——就像这样:

      SET FOREIGN_KEY_CHECKS = 0;
      drop table if exists customers;
      drop table if exists orders;
      drop table if exists order_details;
      SET FOREIGN_KEY_CHECKS = 1;
      

      如需了解更多信息,请查看以下链接:

      http://alvinalexander.com/blog/post/mysql/drop-mysql-tables-in-any-order-foreign-keys/

      【讨论】:

      • 设置外键检查对我帮助很大。
      猜你喜欢
      • 2021-09-03
      • 2017-06-11
      • 1970-01-01
      • 2018-09-11
      • 2018-07-18
      • 2019-05-25
      • 2014-11-11
      • 2018-05-12
      相关资源
      最近更新 更多