【问题标题】:Is there any harm in resetting the auto-increment?重置自动增量有什么害处吗?
【发布时间】:2011-01-07 13:16:57
【问题描述】:

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

我想用自动增量来填补这些空白。 如果我重置它..有什么危害吗?

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

mysql> ALTER TABLE tbl AUTO_INCREMENT = 1;

【问题讨论】:

标签: mysql database auto-increment


【解决方案1】:

可能非常危险,因为您可以再次获得一个已经在使用的号码。

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

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

再想想差距的存在会导致什么真正的问题。通常这只是一个审美问题。

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

【讨论】:

  • 数字太大怎么办?
  • 如果数字太大,有两种情况(两种都是不好的):因为有间隙而太大,或者即使没有间隙也太大。在第二种情况下,除了重新考虑架构之外,您无能为力。在第一种情况下,您可以删除并重新创建整个列。但这会重新编号每一行,这也可能是不可能的。
【解决方案2】:

这样做您可能不会获得任何好处,而且您很容易通过覆盖行来搞砸您的应用程序,因为您要重置 ID 的计数。 (换句话说,下次插入一行时,它会覆盖 ID 为1 的行,然后是2 等。)填补这些空白会得到什么?如果数字太大,只需将其更改为larger number(如BIGINT)。


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

【讨论】:

  • 不,你不会覆盖任何东西,只有主键可以自动递增,所以你会得到一个重复键错误,如果你能这样做的话。
【解决方案3】:

我同意 musicfreak... 整数 (int(10)) 的最大值为 4,294,967,295(无符号粗略)。如果您需要更高,切换到BIGINT 可以让您达到 18,446,744,073,709,551,615。

【讨论】:

  • 除非您在进行大量删除和插入操作,否则我认为您应该在需要比 unsigned int 更大之前让数据库崩溃。
【解决方案4】:

FWIW...根据MySQL docs申请

ALTER TABLE tbl AUTO_INCREMENT = 1

tbl 包含现有数据的地方应该没有影响:

改变值 AUTO_INCREMENT 计数器用于 新行,这样做:

ALTER TABLE t2 AUTO_INCREMENT = 值;

您不能将计数器重置为 值小于或等于任何 已经被使用了。对于 MyISAM,如果 该值小于或等于 当前的最大值 AUTO_INCREMENT 列,值为 重置为当前最大值加一。 对于 InnoDB,如果值小于 中的当前最大值 列,不会发生错误,并且 当前序列值没有改变。

我为 MyISAM 表运行了一个小测试,证实了这一点。

因此,您的问题的答案是:没有害处,不,它不会填补空白。正如其他响应者所说:更改数据类型似乎是最不痛苦的选择。

【讨论】:

    【解决方案5】:

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

    你能做很多停机时间吗?如果是的话,我能想到两种选择:

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

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

    当然,这两者都忽略了参照完整性。我假设这不是问题(不用作外键的日志语句等)。

    【讨论】:

      【解决方案6】:

      是否有差距真的很重要吗?

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-02
        • 2011-12-19
        • 2019-05-11
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 2016-07-21
        相关资源
        最近更新 更多