MySQL:忽略外键约束删除一行

68

我正在处理几个表格,它们之间存在一些数据不一致的问题... 其中一两个表格在特定表(称为X表)上有一个外键约束,但是该表中有多行具有外键列。

我的目标是删除X表中的重复行,但是外键约束阻止了我这样做。是否有一种方法可以强制删除这些行而忽略外键约束,因为我知道自己在做什么?


1
请注意,使用 SET foreign_key_checks = 0 可能会破坏您的数据库。只有在确切知道其结果时才使用它。我仅在我的 PHP 备份脚本中使用它。 - DevWL
当然,这样做是很危险的,我只会在确切知道自己在做什么时使用它。 - Xavier_Ex
4个回答

178

SET foreign_key_checks = 0;

这会防止MySQL检查外键。但一定要在完成后将其设置回1。

此外,您还可以删除外键,然后稍后再添加它,以仅影响单个键

ALTER TABLE tableName DROP FOREIGN KEY fk;


3
如果您立即注销会话,则不必将外键检查设置回1。 - dewd
我有多个表格,所以我想从所有表格中删除这个字段,那么我该怎么做呢?现在的方法行不通。 - karan
4
请记住,这将留下孤立的行,它不会强制删除任何子记录。 - Luke
之后您可能想要运行一个完整性检查。 - phil294
SET foreign_key_checks = 0; 对我无效。我仍然会收到“无法删除或更新父行:外键约束失败”的错误提示。 - James Parker

16

2

正如一些人已经指出的那样,忽略限制外键会导致数据库不一致。在这种情况下,防止DELETE是你想要的。

在执行主查询之前,最好先删除相关行:

DELETE FROM cities WHERE country_id=3;
-- Afterwards you delete rows from the parent table without error:
DELETE FROM countries WHERE country_id=3;

或者,更好的方法是只需更改外键一次,让它自动执行删除(级联):
ALTER TABLE cities DROP FOREIGN KEY `fk.cities.country_id`;
ALTER TABLE cities ADD CONSTRAINT `fk.cities.country_id` FOREIGN KEY (country_id)
    REFERENCES countries (id) ON UPDATE CASCADE ON DELETE CASCADE;
-- From now on, just delete from the parent table:
DELETE FROM countries WHERE country_id=3;

0

对于已接受的答案进行扩展,您必须在DROP FOREIGN KEY之后指定约束名称。

您可以通过发出SHOW CREATE TABLE来检查约束名称。

> SHOW CREATE TABLE tbl_name

Create Table: CREATE TABLE `tbl_name` (
  `id` int(11) DEFAULT NULL,
  `foo_id` int(11) DEFAULT NULL,
  CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`foo_id`)
)

在这种情况下,“foo_ibfk_1”是约束名称。因此,您可以编写:
ALTER TABLE tableName DROP FOREIGN KEY foo_ibfk_1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接