为什么我的团队中没有TRUNCATE?即使我有一个删除级联集,我得到:

错误1701(42000):无法截断外键约束(mytest.instance,constraint instance_ibfk_1 foreign key(GroupID)REFERENCES 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约束的行。


根据mysql文档,TRUNCATE不能用于具有外键关系的表。没有完整的替代AFAIK。

删除约束仍然不会调用ON DELETE和ON UPDATE。我能想到的唯一解决方案是:

删除所有行,删除外键,截断,重新创建键删除所有行,重置auto_increment(如果使用)

MySQL中的TRUNCATE似乎还不是一个完整的功能(它也不会调用触发器)。参见注释


我只需要:

DELETE FROM mytest.instance;
ALTER TABLE mytest.instance AUTO_INCREMENT = 1;

答案确实是zerkms提供的,如选项1所述:

选项1:不会对数据完整性造成损害:移除约束执行TRUNCATE手动删除现在无处引用的行创建约束

棘手的部分是消除约束,所以我想告诉你,如果有人需要知道如何做到这一点:

运行SHOW CREATE TABLE<TABLE Name>查询以查看FOREIGN KEY的名称(下图中的红色框):运行ALTER TABLE<表名>DROP FOREIGN KEY<外键名>。这将删除外键约束。删除关联的索引(通过表结构页),就完成了。

要重新创建外键:

ALTER TABLE <Table Name>
ADD FOREIGN KEY (<Field Name>) REFERENCES <Foreign Table Name>(<Field Name>);

虽然有人问我这个问题,但我不知道,但现在如果您使用phpMyAdmin,您只需打开数据库并选择要截断的表即可。

底部有一个下拉列表,包含许多选项。打开它并选择标题“删除数据或表格”下的“空”选项。它会自动转到下一页,在复选框中有一个名为“启用外键检查”的选项。只需取消选中它,然后按“是”按钮,所选表格将被截断。

也许它在内部运行user447951答案中建议的查询,但从phpMyAdmin界面使用它非常方便。


你能做到的

DELETE FROM `mytable` WHERE `id` > 0

获取旧的外键检查状态和sql模式是截断/删除表的最佳方法,就像Mysql Workbench在将模型同步到数据库时所做的那样。

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;

如果表的数据库引擎不同,则会出现此错误,因此请将其更改为InnoDB

ALTER TABLE my_table ENGINE = InnoDB;

如果您使用的是phpMyAdmin,那么很简单。

只需取消选中SQL选项卡下的启用外键检查选项,然后运行TRUNCATE<TABLE_NAME>


只需使用CASCADE

TRUNCATE "products" RESTART IDENTITY CASCADE;

但要做好级联删除的准备)


在MYSQL数据库上测试

解决方案1:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;

解决方案2:

DELETE FROM table1;
ALTER TABLE table1 AUTO_INCREMENT = 1;
TRUNCATE table1;

这对我有用。我希望,这对你也有帮助。谢谢你提出这个问题。


另一种解决方法是删除表中的所有行,然后重置自动递增列:

delete from table_name where 1

然后运行:

ALTER TABLE table_name AUTO_INCREMENT = 1

如何截断外键约束表?本图将演示如何在使用外键约束截断表时解决mysql错误。如果您使用的是PHPMYADMIN,那么非常容易用外键约束截断表。

登录PHPMYADMIN并单击要截断的表。然后转到SQL选项卡放置代码以截断SQL中的表编辑示例截断表学生;将学生替换为表的名称。在编辑器底部,取消选中“启用外键检查”复选框,如下所示:

它会像魔法一样工作。


如果您使用的是laravel迁移,可以使用facade助手来实现

更喜欢使用雄辩的对象,回答“雄辩”的方式

 Schema::disableForeignKeyConstraints();
 Teacher::truncate();
 Schema::enableForeignKeyConstraints();

在Laravel 7和8中,为了兼容4个数据库(MySql、Postgres、SQLite和SqlServer),并且没有Elquent,您可以使用:

Schema::disableForeignKeyConstraints();
    DB::table('teachers')->truncate();
Schema::enableForeignKeyConstraints();