无法从空表中截断外键约束中引用的表

时间:2017-10-19 17:07:20

标签: mysql foreign-keys

我有以下表格:

CREATE TABLE `companies_investorfundinground` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `funding_round_id` int(11) NOT NULL,
  `investor_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id` (`funding_round_id`),
  KEY `companies_investor_investor_id_30d4fd3e_fk_companies_investor_id` (`investor_id`),
  CONSTRAINT `companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id` FOREIGN KEY (`funding_round_id`) REFERENCES `companies_fundinground` (`id`),
  CONSTRAINT `companies_investor_investor_id_30d4fd3e_fk_companies_investor_id` FOREIGN KEY (`investor_id`) REFERENCES `companies_investor` (`id`)
)


CREATE TABLE `companies_fundinground` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `funding_round_code` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `companies_fundinground_447d3092` (`company_id`),
  CONSTRAINT `companies_company_id_36dd5970_fk_companies_company_entity_ptr_id` FOREIGN KEY (`company_id`) REFERENCES `companies_company` (`entity_ptr_id`)
)

我能够截断公司_investorfundinground。

我尝试删除companies_fundinground,但收到错误:

  

无法截断外键约束中引用的表companies_funding_round_id_8edc4cc4_fk_companies_fundinground_id

如果公司_investorfundinground完全被截断,为什么我会收到此错误?

1 个答案:

答案 0 :(得分:2)

TRUNCATE TABLE相当于删除表并将其重新创建为新表。这会打破外键引用。

https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html中说:

  

逻辑上,TRUNCATE TABLE类似于删除所有行的DELETE语句,或者删除DROP TABLE和CREATE TABLE语句的序列。为了实现高性能,它绕过了删除数据的DML方法。因此,它不能回滚,它不会导致触发ON DELETE触发器,并且不能对具有父子外键关系的InnoDB表执行。

考虑另一种方式:如果TRUNCATE TABLE应该快速有效,是否值得花时间检查子表以查看它是否有任何引用行?该表可能有数百万行,但在所有行的外键列中都有NULL。

如果您确定不会破坏子表,则可以使用解决方法:

mysql> create table p ( id int primary key );

mysql> create table f ( pid int, foreign key (pid) references p(id));

mysql> truncate table p;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
(`test`.`f`, CONSTRAINT `f_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `test`.`p` (`id`))

mysql> set foreign_key_checks=0;

mysql> truncate table p;

mysql> set foreign_key_checks=1;