关于mysql:如何截断外键约束表?

How to truncate a foreign key constrained table?

为什么在mygroup上的截断不起作用?即使我有ON DELETE CASCADE SET,我也得到:

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (mytest.instance, CONSTRAINT instance_ibfk_1 FOREIGN KEY (GroupID) REFERENCES mytest.mygroup (ID))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;

是的,你可以:

1
2
3
4
5
6
SET FOREIGN_KEY_CHECKS = 0;

TRUNCATE table1;
TRUNCATE table2;

SET FOREIGN_KEY_CHECKS = 1;

有了这些语句,您就有可能在表中插入不符合FOREIGN KEY约束的行。


不能在表上应用FK约束(TRUNCATEDELETE不同)。

要解决这一问题,请使用以下任一解决方案。两者都存在破坏数据完整性的风险。

选项1:

  • 删除约束
  • 执行TRUNCATE
  • 手动删除现在无处引用的行
  • 创建约束
  • 选项2:由用户447951在其答案中建议

    1
    2
    3
    SET FOREIGN_KEY_CHECKS = 0;
    TRUNCATE table $table_name;
    SET FOREIGN_KEY_CHECKS = 1;


    我只需要:

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


    根据mysql文档,truncate不能用于具有外键关系的表。阿法克没有完全的替代品。

    删除约束仍不调用on delete和on update。ATM唯一能想到的解决方案是:

    • 删除所有行,删除外键,截断,重新创建键
    • 删除所有行,重置自动增量(如果使用)

    it would see truncate in mysql is not a complete feature yet(it also not invoke triggers).见评论


    你可以做到

    1
    DELETE FROM `mytable` WHERE `id` > 0


    虽然这个问题是在5年前被问到的,我不知道MySQL中有这个工具,但是现在如果您使用phpmyadmin,您可以简单地打开数据库,然后选择要截断的表。在底部有一个下拉列表,其中列出了许多选项。打开它并在标题"删除数据或表"下选择"空"选项。它会自动转到下一页,在该页的复选框中有一个名为"启用外键检查"的选项。只需取消选中它,然后按"是"按钮,所选表将被截断。可能在内部运行用户447951回答中建议的查询。但是从phpmyadmin接口使用非常方便。


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

    Option 1: which does not risk damage to data integrity:

  • Remove constraints
  • Perform TRUNCATE
  • Delete manually the rows that now have references to nowhere
  • Create constraints
  • 棘手的部分是消除约束,所以我想告诉你,如果有人需要知道如何做到这一点:

  • 运行SHOW CREATE TABLE

    查询,查看您的外键名(下图中的红色框):

    enter image description here

  • 运行ALTER TABLE

  • DROP FOREIGN KEY 。这将删除外键约束。

  • 删除关联的索引(通过表结构页),就完成了。

  • 要重新创建外键:

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

  • 如果你使用phpmyadmin,很容易。

    只需取消选中SQL选项卡下的Enable foreign key checks选项并运行TRUNCATE

    enter image description here


    只用级联

    1
    TRUNCATE"products" RESTART IDENTITY CASCADE;

    但要准备好级联删除)


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

    1
    ALTER TABLE my_table ENGINE = InnoDB;

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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;