强制删除 MySQL 记录,跳过外键约束。

166

我试图删除数据库中除一个之外的所有表格,但结果出现以下错误:

无法删除或更新父行:违反外键约束

当然,我可以通过试错找出这些关键约束是什么,并最终删除所有表格,但我想知道是否有一种快速的方法来强制删除所有表格(因为我将能够重新插入那些不想删除的表格)。

谷歌搜索引导我访问了某个网站,该网站建议使用以下方法:

mysql> SET foreign_key_checks = 0;
mysql> drop table ...
mysql> SET foreign_key_checks = 1;

简短的回答是它并没有真正起到作用,因为我在删除了更多的表之后仍然收到了相同的错误。我在Stack Overflow上看到了一些获取与某个表相关联的所有外键的方法,但这太耗时了,除非我将其全部编写脚本(如果没有其他选择,这是可行的)。

数据库是4.1版本,所以我无法使用DROP DATABASE

有什么想法吗?


1
你为什么选择那个被选中的答案,它甚至没有提供解决你问题的方法? - Sanjay
7个回答

476
这可能对通过搜索来到这里的某些人有用。 请确保您要删除的是一个表(table)而不是一个视图(view)
SET foreign_key_checks = 0;
-- 删除表
drop table ...
-- 删除视图
drop view ...
SET foreign_key_checks = 1;
SET foreign_key_checks = 0 是将外键检查设置为关闭,然后 SET foreign_key_checks = 1 是将外键检查再次打开。在关闭检查时,可以删除表,然后打开检查以保持表结构的完整性。

6
这是一个更好的正确答案。解决了删除所有表或仅删除几个表的问题。太棒了! - Luke Stevenson
@PAT 非常感谢,它起作用了。虽然在Mysql查询浏览器中无法工作。你救了我的一天。 - MaNn
运行得非常完美,我使用了这个方法,因为我不能删除整个数据库。 - Pablo Pazos
1
我同意这通常是正确的解决方案,但是提问者@johnnyArt明确将其排除为可行选项,因为它对他没有起作用。所以看起来这不是原始问题的正确答案,对吗? - David
这个答案是恰当的、正确的并帮助我解决了我的困惑,但是需要注意有两个 foreign_key_checks 变量:一个全局变量和一个本地(每个会话)变量。命令 SET foreign_key_checks 修改会话变量,而 SET GLOBAL foreign_key_checks 修改全局变量。或者,您可以使用 ALTER TABLE table_name DISABLE KEYS 临时禁用 FK。使用 ALTER TABLE table_name ENABLE KEYS 启用它 - https://tableplus.com/blog/2018/08/mysql-how-to-temporarily-disable-foreign-key-constraints.html - Dimgba Kalu

19

如果你使用的是phpmyadmin,那么这个功能已经存在了。

  • 选择你想要删除的表
  • 从表列表底部的下拉菜单中选择“删除”
  • 一个新页面将被打开,在底部有一个复选框,上面写着“外键检查”,请取消勾选。
  • 接受“是”的确认后,确认删除。

4
您可以按照以下步骤操作,我使用这个方法成功地删除了带有约束的表格。在上面的评论中已经解释了解决方案,我只是为此添加了屏幕截图- enter image description here

1
这是一个重复的回答,与最高票答案完全相同,而该答案是在四年前发布的。 - chb

3

MySQL中存在“删除数据库”的功能,但如果您想保留表结构,这里有一个方法:

mysqldump --no-data --add-drop-database --add-drop-table -h主机名 -u用户名 -p > dump.sql

这是一个程序,而不是mysql命令。

然后,登录到mysql并执行以下命令:

source dump.sql;


3

终端上一次性删除所有表的简单解决方法。

这需要在您的mysql shell中进行几个步骤(虽然不是一步解决方案),但这对我起作用并挽救了我的一天。

适用于服务器版本:5.6.38 MySQL Community Server (GPL)

我遵循的步骤:

 1. generate drop query using concat and group_concat.
 2. use database
 3. turn off / disable foreign key constraint check (SET FOREIGN_KEY_CHECKS = 0;), 
 4. copy the query generated from step 1
 5. re enable foreign key constraint check (SET FOREIGN_KEY_CHECKS = 1;)
 6. run show table

MySQL shell

$ mysql -u root -p
Enter password: ****** (your mysql root password)
mysql> SYSTEM CLEAR;
mysql> SELECT CONCAT('DROP TABLE IF EXISTS `', GROUP_CONCAT(table_name SEPARATOR '`, `'), '`;') AS dropquery FROM information_schema.tables WHERE table_schema = 'emall_duplicate';
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| dropquery                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| DROP TABLE IF EXISTS `admin`, `app`, `app_meta_settings`, `commission`, `commission_history`, `coupon`, `email_templates`, `infopages`, `invoice`, `m_pc_xref`, `member`, `merchant`, `message_templates`, `mnotification`, `mshipping_address`, `notification`, `order`, `orderdetail`, `pattributes`, `pbrand`, `pcategory`, `permissions`, `pfeatures`, `pimage`, `preport`, `product`, `product_review`, `pspecification`, `ptechnical_specification`, `pwishlist`, `role_perms`, `roles`, `settings`, `test`, `testanother`, `user_perms`, `user_roles`, `users`, `wishlist`; |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> USE emall_duplicate;
Database changed
mysql> SET FOREIGN_KEY_CHECKS = 0;                                                                                                                                                   Query OK, 0 rows affected (0.00 sec)

// copy and paste generated query from step 1
mysql> DROP TABLE IF EXISTS `admin`, `app`, `app_meta_settings`, `commission`, `commission_history`, `coupon`, `email_templates`, `infopages`, `invoice`, `m_pc_xref`, `member`, `merchant`, `message_templates`, `mnotification`, `mshipping_address`, `notification`, `order`, `orderdetail`, `pattributes`, `pbrand`, `pcategory`, `permissions`, `pfeatures`, `pimage`, `preport`, `product`, `product_review`, `pspecification`, `ptechnical_specification`, `pwishlist`, `role_perms`, `roles`, `settings`, `test`, `testanother`, `user_perms`, `user_roles`, `users`, `wishlist`;
Query OK, 0 rows affected (0.18 sec)

mysql> SET FOREIGN_KEY_CHECKS = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW tables;
Empty set (0.01 sec)

mysql> 

1

表1 {T_Id, T_Name, TT_Id(可为空)(在表2上作为外键,指向列TT_ID)}

表2 {TT_ID,TT_Title}

1- make the foreign Key relation null able on the table1
2- update table1 set TT_ID = null where T_ID = ?
3- delete from table1

现在您可以删除表1的数据并保留表2的数据。

-51

3
哦,我现在感觉好愚蠢啊,我一直在用数据库的实际名称代替单词“DATABASE”,而不是之后再添加它,谢谢你们两位 +1。 - johnnyArt
19
这不是答案。 - Freelancer
7
这是对问题的正确回答,个人不明白为什么会有负评。提问者想要删除数据库,但不知道如何操作并正在寻找替代方案。这个回答实际上回答了原始问题,帮助提问者解决了困惑。这得到了提问者的认可。 - Robert Pounder
6
@RobertPounder 那正是我的目标,也是我加入这个网站以来一直追求的。我欣赏您的观点。 - Otávio Décio
3
@RobertPounder,SO不仅仅是帮助提问者,它还相当于一个可搜索的“如何”资源。我来到这个主题是因为我需要禁用外键约束检查,而谷歌把我带到了这里。我很高兴删除数据库是对于提问者的一个好的解决方法,但下面的答案实际上是正确的答案,适用于“通过绕过外键约束来强制删除 mysql”。 - Val Redchenko
显示剩余3条评论

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