如何正确地截断表格?

42

我使用ruby的datamapper来存储数据到某些表格。

其中一些表格有大量信息,当用户“重建数据库”时,我想把它们清空(它基本上会删除所有内容并重新计算数据)。

我最初尝试了Forum.all.destroy,并对所有不同的表格都执行了此操作,但是我注意到其中一些表格在phpmyadmin中仍未被删除。我只能想象这是因为外键的缘故,尽管我真的不知道,因为我的另一个表格,它具有外键,已经成功删除了。更不用说,我宁愿将其“归零”,以便键不会变得非常大(例如键号500,000)。

然后我尝试使用下面的代码运行它,但由于“外键约束”,它无法清除表格。我希望强制它工作,因为我确切地知道我正在清除所有互相依赖的表格(我只是没有清除2个表格,一个设置表和一个随机存储表,两者都没有使用外键)。

到目前为止,我已经...

adapter = DataMapper.repository(:default).adapter
adapter.execute('TRUNCATE TABLE `forums`, `dates`, `remarks`');

除了MySQL语法明显有误之外,那应该没问题了。所以这是第一件事。

我在phpMyAdmin中逐个执行时,它会显示:

Cannot truncate a table referenced in a foreign key constraint
2个回答

99

计划 A:

SET FOREIGN_KEY_CHECKS = 0; -- Disable foreign key checking.
TRUNCATE TABLE forums;
TRUNCATE TABLE dates;
TRUNCATE TABLE remarks;
SET FOREIGN_KEY_CHECKS = 1; -- Enable foreign key checking.

备选方案:

您应该先截断子表,然后再截断父表。

禁用外键检查会冒进入不符合约束条件的行到您的表中的风险,可能导致未定义的行为。


有没有想过用Ruby怎么做?我尝试在应用程序中单独运行每个命令,但它并没有删除任何内容。然后我尝试按顺序在phpmyadmin中逐个运行它们,但仍然显示“#1701-无法截断引用外键约束的表”。 - Tallboy
1
算了!它起作用了……它只在毫秒级别存在,然后重新添加了我的数据,我没有注意到它实际上被截断了。谢谢! - Tallboy
1
我已经截断了子表,但在删除父表时仍然失败。无论如何,我现在使用了禁用外键检查的hack方法。 - inquisitive

14

使用以下代码替代禁用外键检查。

您可以使用以下代码。

DELETE FROM forums;
ALTER TABLE forums AUTO_INCREMENT = 1;

DELETE FROM dates;
ALTER TABLE dates AUTO_INCREMENT = 1;

DELETE FROM remarks;
ALTER TABLE remarks AUTO_INCREMENT = 1;

它将仅删除所有行并使id从1开始递增。


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