重置自动增量有什么危害吗?

时间:2010-01-21 01:06:23

标签: mysql database auto-increment

我有1亿行,而且它太大了。 我看到很多差距。 (因为我删除,添加,删除,添加。)

我想用自动增量填补这些空白。 如果我确实重置它......有没有哈利?

如果我这样做,它会填补空白吗?:

mysql> ALTER TABLE tbl AUTO_INCREMENT = 1;

6 个答案:

答案 0 :(得分:9)

可能非常危险,因为您可以再次获得已经使用过的数字。

您建议再次将序列重置为1。它只会产生1,2,3,4,5,6,7,......等等,无论这些数字是否存在差距。

更新:根据Martin的回答,由于存在危险,MySQL甚至不会让你这样做。它会将计数器重置为至少当前值+ 1。

再次思考间隙存在导致的真正问题。通常这只是一个美学问题。

如果数字太大,请切换到更大的数据类型(bigint应该足够多)。

答案 1 :(得分:6)

FWIW ......根据MySQL docs申请

ALTER TABLE tbl AUTO_INCREMENT = 1

其中tbl包含现有数据应该没有效果:

  

要更改的值   AUTO_INCREMENT计数器用于   新行,执行此操作:

     

ALTER TABLE t2 AUTO_INCREMENT = value;

     

您无法将计数器重置为a   值小于或等于任何值   已经被使用过。对于MyISAM,如果   该值小于或等于   目前的最大值   AUTO_INCREMENT列,值为   重置为当前最大值加1。   对于InnoDB,如果值小于   当前的最大值   列,没有错误发生和   当前序列值不会改变。

我进行了一项小测试,确认了MyISAM表。

所以你问题的答案是:没有伤害,也不会填补空白。正如其他响应者所说:数据类型的变化看起来是最不痛苦的选择。

答案 2 :(得分:5)

您可能无法从中获得任何好处,并且您可以通过覆盖行轻松搞砸您的应用程序,因为您将重置ID的计数。 (换句话说,下次插入行时,它会覆盖ID为1的行,然后覆盖2等。)填补空白会得到什么?如果数字太大,只需将其更改为larger number(例如BIGINT)。


修改:我已经纠正了。它根本不会做任何事情,这支持我的观点,你应该只将列的类型更改为更大的整数类型。 BIGINT的最大可能值为2 ^ 64,超过18 quintillion 。如果你现在只有1亿行,那么在可预见的未来,这应该是很多

答案 3 :(得分:2)

我同意musicfreak ...整数(int(10))的最大值是4,294,967,295(unsigned ofcoarse)。如果你需要更高,切换到BIGINT会带来高达18,446,744,073,709,551,615。

答案 4 :(得分:1)

由于您无法更改下一个自动增量值,因此您还有其他选项。数据类型切换可以完成,但它似乎有点令我不安,因为你实际上没有那么多行。您必须确保您的代码可以处理大的ID,这对您来说可能是困难的,也可能不是。

你能做多停机吗?如果你是,我可以想到两个选择:

  1. 转储/重新加载数据。您可以这样做,因此它不会保留ID号。例如,您可以使用SELECT ... INTO将数据sans-ID复制到具有相同DDL的新表。然后删除旧表并将新表重命名为旧名称。根据有多少数据,这可能需要注意时间(和临时磁盘空间)。

  2. 您可以制作一个小程序来发出UPDATE语句来更改ID。如果你让它慢慢运行,它会随着时间的推移对你的ID进行“碎片整理”。然后你可以暂时停止插入(只需一两分钟),更新最后的ID,然后重新启动它。更新最后的ID后,您可以将AUTO_INCREMENT值更改为下一个数字,并且您的孔将消失。这不应该导致任何真正的停机时间(至少在InnoDB上),但可能需要一段时间,具体取决于您的程序的积极程度。

  3. 当然,这两个都忽略了参照完整性。我假设这不是问题(没有用作外键的日志语句,或者其他一些)。

答案 5 :(得分:0)

是否存在差距真的重要吗?

如果您真的想回去填充它们,您可以随时关闭自动增量,并在每次要插入行时手动扫描下一个可用的ID - 记住锁定表以避免竞争条件,当然。但是,为了获得不大的收益,还有很多工作要做。

你真的需要一个代理键吗?根据数据(您还没有提到架构),您可能会找到一个自然键。