如何截断外键约束表?

发布于 2024-10-27 06:25:18 字数 790 浏览 7 评论 0原文

为什么 mygroup 上的 TRUNCATE 不起作用? 即使我有 ON DELETE CASCADE SET 我得到:

错误 1701 (42000):无法截断外键约束中引用的表 (mytest.instance、CONSTRAINT instance_ibfk_1 FOREIGN KEY ( 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;

Why doesn't a TRUNCATE on mygroup work?
Even though I have ON DELETE CASCADE SET I get:

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))

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

情深如许 2024-11-03 06:25:18

是的,您可以:

SET FOREIGN_KEY_CHECKS = 0;

TRUNCATE table1;
TRUNCATE table2;

SET FOREIGN_KEY_CHECKS = 1;

使用这些语句,您可能会冒着将不遵守 FOREIGN KEY 约束的行放入表中的风险。

Yes you can:

SET FOREIGN_KEY_CHECKS = 0;

TRUNCATE table1;
TRUNCATE table2;

SET FOREIGN_KEY_CHECKS = 1;

With these statements, you risk letting in rows into your tables that do not adhere to the FOREIGN KEY constraints.

荒人说梦 2024-11-03 06:25:18

您无法TRUNCATE应用了FK约束的表(TRUNCATEDELETE不同)。

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

选项 1:

  1. 删除约束
  2. 执行 TRUNCATE
  3. 手动删除现在无处引用的行
  4. 创建约束

选项 2: user447951他们的答案中建议

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

You cannot TRUNCATE a table that has FK constraints applied on it (TRUNCATE is not the same as DELETE).

To work around this, use either of these solutions. Both present risks of damaging the data integrity.

Option 1:

  1. Remove constraints
  2. Perform TRUNCATE
  3. Delete manually the rows that now have references to nowhere
  4. Create constraints

Option 2: suggested by user447951 in their answer

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;
独闯女儿国 2024-11-03 06:25:18

我会简单地这样做:

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

I would simply do it with :

DELETE FROM mytest.instance;
ALTER TABLE mytest.instance AUTO_INCREMENT = 1;
一桥轻雨一伞开 2024-11-03 06:25:18

如果您使用 phpMyAdmin,则很容易。

只需取消选中 SQL 选项卡下的启用外键检查 选项并运行 TRUNCATE

在此处输入图像描述

Easy if you are using phpMyAdmin.

Just uncheck Enable foreign key checks option under SQL tab and run TRUNCATE <TABLE_NAME>

enter image description here

我为君王 2024-11-03 06:25:18

在 MYSQL 数据库上进行测试

解决方案 1:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;

解决方案 2:

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

这对我有用。我希望,这也会对您有所帮助。感谢您提出这个问题。

Tested on MYSQL Database

Solution 1:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;

Solution 2:

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

This works for me. I hope, this will help you also. Thanks for asking this question.

二货你真萌 2024-11-03 06:25:18

你可以做

DELETE FROM `mytable` WHERE `id` > 0

you can do

DELETE FROM `mytable` WHERE `id` > 0
过气美图社 2024-11-03 06:25:18

根据 MySQL 文档,TRUNCATE 不能用于具有外键关系的表。据我所知,没有完全的替代方案。

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

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

似乎MySQL中的TRUNCATE还不是一个完整的功能(它也不调用触发器)。
查看评论

As per MySQL documentation, TRUNCATE cannot be used on tables with foreign key relationships. There is no complete alternative AFAIK.

Dropping the constraint still does not invoke the ON DELETE and ON UPDATE.
The only solution I can ATM think of is to either:

  • delete all rows, drop the foreign keys, truncate, recreate keys
  • delete all rows, reset auto_increment (if used)

It would seem TRUNCATE in MySQL is not a complete feature yet (it also does not invoke triggers).
See comment

初懵 2024-11-03 06:25:18

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

  • 底部有一个包含许多选项的下拉菜单。打开它并选择删除数据或表标题下的清空选项。
  • 它会自动带您进入下一页,其中复选框中有一个名为启用外键检查的选项。只需取消选择它并按Yes按钮,所选的表就会被截断。

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

While this question was asked I didn't know about it, but now if you use phpMyAdmin you can simply open the database and select the table(s) you want to truncate.

  • At the bottom there is a drop down with many options. Open it and select Empty option under the heading Delete data or table.
  • It takes you to the next page automatically where there is an option in checkbox called Enable foreign key checks. Just unselect it and press the Yes button and the selected table(s) will be truncated.

Maybe it internally runs the query suggested in user447951's answer, but it is very convenient to use from phpMyAdmin interface.

暖阳 2024-11-03 06:25:18

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

选项 1:不会损害数据完整性:

  1. 删除限制
  2. 执行截断
  3. 手动删除现在无处引用的行
  4. 创建约束

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

  1. 运行 SHOW CREATE TABLE

    查询来查看你的国外KEY的名字(下图中红框):

    在此处输入图像描述

  2. 运行 ALTER TABLE <表名称>;删除外键<外键名称>。这将删除外键约束。

  3. 删除关联的索引(通过表结构页面),即可完成。

重新创建外键:

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

Answer is indeed the one provided by zerkms, as stated on Option 1:

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

  1. Remove constraints
  2. Perform TRUNCATE
  3. Delete manually the rows that now have references to nowhere
  4. Create constraints

The tricky part is Removing constraints, so I want to tell you how, in case someone needs to know how to do that:

  1. Run SHOW CREATE TABLE <Table Name> query to see what is your FOREIGN KEY's name (Red frame in below image):

    enter image description here

  2. Run ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign Key Name>. This will remove the foreign key constraint.

  3. Drop the associated Index (through table structure page), and you are done.

to re-create foreign keys:

ALTER TABLE <Table Name>
ADD FOREIGN KEY (<Field Name>) REFERENCES <Foreign Table Name>(<Field Name>);
放血 2024-11-03 06:25:18

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

delete from table_name where 1

然后运行:

ALTER TABLE table_name AUTO_INCREMENT = 1

Another workaround is delete all rows in the table then reset auto-increment columns:

delete from table_name where 1

then Run:

ALTER TABLE table_name AUTO_INCREMENT = 1
静待花开 2024-11-03 06:25:18

如何截断外键约束表?
此图将演示如何解决使用外键约束截断表时的 mysql 错误。
如果您使用 PHPMYADMIN,则很容易截断具有外键约束的表。

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

在此处输入图像描述

它会像魔术一样工作。

How to truncate a foreign key constrained table?
This illustration will demonstrate how to solve mysql error when truncating a table with foreign key constraint.
If you are using PHPMYADMIN, it is very easy to truncate a table with foreign key constraint.

  1. Login to PHPMYADMIN and click the table you want to truncate.
  2. Then go to SQL tab Place your code to truncate the table in the SQL
    Editor example truncate table students; Replace students with the
    name of the table.
  3. At the bottom of the editor untick the "Enable foreign key checks" checkbox as shown below:

enter image description here

It will work like magic.

已下线请稍等 2024-11-03 06:25:18

如果您使用 Laravel 迁移,则可以使用 Facades 来完成此操作。

更喜欢使用 Eloquent 对象,请回答“Eloquent”方式

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

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

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

if you are using laravel migrations, you can do this using facades helpers

prefer to use Eloquent objects, answer the "Eloquent" way

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

In Laravel 7 and 8, for compatibility across 4 databases (MySql, Postgres, SQLite and SqlServer) and no Eloquent, you can use:

Schema::disableForeignKeyConstraints();
    DB::table('teachers')->truncate();
Schema::enableForeignKeyConstraints();
究竟谁懂我的在乎 2024-11-03 06:25:18

获取旧的外键检查状态和 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;

Getting the old foreign key check state and sql mode are best way to truncate / Drop the table as Mysql Workbench do while synchronizing model to database.

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;
季末如歌 2024-11-03 06:25:18

如果表的数据库引擎不同,您将收到此错误,因此将它们更改为 InnoDB

ALTER TABLE my_table ENGINE = InnoDB;

If the database engine for tables differ you will get this error so change them to InnoDB

ALTER TABLE my_table ENGINE = InnoDB;
不气馁 2024-11-03 06:25:18

只需使用 CASCADE

TRUNCATE "products" RESTART IDENTITY CASCADE;

但要准备好级联删除)

Just use CASCADE

TRUNCATE "products" RESTART IDENTITY CASCADE;

But be ready for cascade deletes )

屋檐 2024-11-03 06:25:18

在进行增删改查操作查询和截断表之前,我们此时使用安全查询。

对于像删除查询这样的粗略操作,您可以编写此命令。

SET SQL_SAFE_UPDATES = 0;

之后该查询可以将零重写为一以进行安全查询。

 SET SQL_SAFE_UPDATES = 1;

对于截断表,我们可以在截断查询之前编写以下命令。

SET FOREIGN_KEY_CHECKS = 0;

之后该查询可以将零重写为一以进行安全查询。

 SET FOREIGN_KEY_CHECKS = 1;

Before crud operation query and truncating table, we use a safe query at that point.

For a crude operation like deleting a query, you can write this command.

SET SQL_SAFE_UPDATES = 0;

after this that query can rewrite zero to one for safe query.

 SET SQL_SAFE_UPDATES = 1;

For truncate tables, we can write the command below before truncating the query.

SET FOREIGN_KEY_CHECKS = 0;

after that query can rewrite zero to one for safe query.

 SET FOREIGN_KEY_CHECKS = 1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文