尝试截断表时出现MySQL错误

5

我在MySQL Server 5.5上遇到了截断表的问题。

我尝试截断的表中有一列在另一个表中作为外键使用。

两个涉及表的CREATE TABLE如下:

CREATE TABLE `tbluser` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `creationDate` datetime NOT NULL,
  `creationUserId` int(11) NOT NULL,
  `updateDate` datetime NOT NULL,
  `updateUserId` int(11) NOT NULL,
  `lastAccess` datetime NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`),
  KEY `FK_tbluser_creationUserId` (`creationUserId`),
  KEY `FK_tbluser_updateUserId` (`updateUserId`),
  CONSTRAINT `FK_tbluser_updateUserId` FOREIGN KEY (`updateUserId`) REFERENCES `tbluser` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_tbluser_creationUserId` FOREIGN KEY (`creationUserId`) REFERENCES `tbluser` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

CREATE TABLE `tblpost` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `content` mediumtext NOT NULL,
  `creationDate` datetime NOT NULL DEFAULT '1901-01-01 00:00:00',
  `creationUserId` int(11) NOT NULL,
  `updateDate` datetime NOT NULL DEFAULT '1901-01-01 00:00:00',
  `updateUserId` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_tblpost_creationUserId` (`creationUserId`),
  KEY `FK_tblpost_updateUserId` (`updateUserId`),
  CONSTRAINT `FK_tblpost_updateUserId` FOREIGN KEY (`updateUserId`) REFERENCES `tbluser` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `FK_tblpost_creationUserId` FOREIGN KEY (`creationUserId`) REFERENCES `tbluser` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

请注意,所有约束都设置为DELETEUPDATE ON CASCADE
当我尝试TRUNCATE表格时:
TRUNCATE TABLE `<databasename>`.`tbluser`;

我收到以下错误信息:

Cannot truncate a table referenced in a foreign key constraint
(`<databasename>`.`tblpost`, 
CONSTRAINT `FK_tblpost_updateUserId` 
FOREIGN KEY (`updateUserId`) 
REFERENCES `<databasename>`.`tbluser` (`id`))

除了这些信息外,还有一个事实,当尝试在MySQL Server 5.1上执行上述操作时,它是有效的!有人知道为什么会发生这种情况吗?
1个回答

4

点击这里查看。TRUNCATE TABLE在这种情况下引发错误是有道理的,但不好的是它没有记录在案。


错误的问题在于我们设置了DELETE ON CASCADE。我认为期望的行为是在Server 5.1上得到的行为,即截断指定的表并删除设置了FK的其他表中的所有数据。 当然,这几乎像是对数据库进行“完全截断”,但我确实指定了DELETE ON CASCADE,这就是它应该做的,不是吗? - Will
我们对项目进行了测试,事实上没有“简单”的解决方案。如果我们按照指定的解决方案并禁用ForeignKeys通知,则在删除用户表中的行时,tblpost上什么也不会发生,这是错误的。我们决定将所有MySQL服务器保持在同一版本上,以避免出现更多类似的问题。感谢a1ex07的精准帮助! - Will
我认为他们应该在文档中说得更清楚一些,比如“无法截断被外键引用的表”,以消除所有的误解。在我看来,之前的版本中存在一个错误,使得 TRUNCATE 在处理 FK 时类似于没有 WHERE 的 DELETE。我意识到这是一个相当有争议的观点,但我的想法是 TRUNCATE 应该比 DELETE 更少地涉及开销,并且不必考虑 FK 约束。 - a1ex07

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