如何截断外键约束表?
-
12-11-2019 - |
题
为什么不 截断,截断 上 mygroup
工作?即使我有 ON DELETE CASCADE SET
我得到:
错误1701(42000):无法截断外键约束中引用的表(
mytest
.instance
,约束instance_ibfk_1
外键(GroupID
)参考资料mytest
.mygroup
(ID
))
drop database mytest;
create database mytest;
use mytest;
CREATE TABLE mygroup (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY
) ENGINE=InnoDB;
CREATE TABLE instance (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
GroupID INT NOT NULL,
DateTime DATETIME DEFAULT NULL,
FOREIGN KEY (GroupID) REFERENCES mygroup(ID) ON DELETE CASCADE,
UNIQUE(GroupID)
) ENGINE=InnoDB;
解决方案
你不能 TRUNCATE
在其上应用了FK约束的表(TRUNCATE
是不一样的 DELETE
).
要解决此问题,请使用以下任一解决方案。两者都存在损害数据完整性的风险。
备选案文1:
- 移除约束
- 表演/表演
TRUNCATE
- 手动删除现在有引用的行 无处可去
- 创建约束
备选案文2: 建议者 用户447951 在 他们的回答
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table $table_name;
SET FOREIGN_KEY_CHECKS = 1;
其他提示
是的,你可以:
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;
TRUNCATE table2;
SET FOREIGN_KEY_CHECKS = 1;
使用这些语句,您可能会让不遵守 FOREIGN KEY
约束条件。
我只想用它来做 :
DELETE FROM mytest.instance;
ALTER TABLE mytest.instance AUTO_INCREMENT = 1;
你可以做到
DELETE FROM `mytable` WHERE `id` > 0
按 mysql文档, ,TRUNCATE不能用于具有外键关系的表。没有完整的替代AFAIK。
删除禁忌仍然不会调用ON DELETE和ON UPDATE。我唯一能想到的解决方案是要么:
- 删除所有行,删除外键,截断,重新创建键
- 删除所有行,重置auto_increment(如果使用)
在MySQL中,TRUNCATE似乎还不是一个完整的功能(它也不会调用触发器)。
见评论
虽然这个问题被问到我不知道它,但现在如果您使用phpMyAdmin,您可以简单地打开数据库并选择要截断的表。
- 在底部有一个有很多选项的下拉。打开它并选择
Empty
标题下的选项Delete data or table
. - 它会自动将您带到下一页,其中复选框中有一个选项称为
Enable foreign key checks
.只需取消选择它,然后按Yes
按钮和选定的表将被截断。
也许它内部运行的查询建议在 user447951的回答, ,但从phpMyAdmin界面使用非常方便。
答案确实如此 由 zerkms, ,如上所述 备选案文1:
备选案文1:不会损害数据完整性的风险:
- 移除约束
- 执行TRUNCATE
- 手动删除现在引用nowhere的行
- 创建约束
棘手的部分是 移除约束, ,所以我想告诉你如何,以防有人需要知道如何做到这一点:
跑
SHOW CREATE TABLE <Table Name>
查询看看你的是什么 外键名称(下图红框):跑
ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign Key Name>
.这将删除外键约束。删除关联的 索引 (通过表结构页面),你就完成了。
要重新创建外键:
ALTER TABLE <Table Name>
ADD FOREIGN KEY (<Field Name>) REFERENCES <Foreign Table Name>(<Field Name>);
只需使用CASCADE
TRUNCATE "products" RESTART IDENTITY CASCADE;
但要准备好级联删除)
如果表的数据库引擎不同,您将收到此错误,因此将它们更改为InnoDB
ALTER TABLE my_table ENGINE = InnoDB;
获取旧的外键检查状态和sql模式是在将模型同步到数据库时截断/删除表的最佳方法。
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;`
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
DROP TABLE TABLE_NAME;
TRUNCATE TABLE_NAME;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;