【问题标题】:How to handle fragmentation of auto_increment ID column in MySQL如何处理 MySQL 中 auto_increment ID 列的碎片
【发布时间】:2010-12-21 22:17:48
【问题描述】:

我有一个带有 auto_increment 字段的表,有时行会被删除,因此 auto_increment 会留下空白。有没有办法避免这种情况,或者如果没有,至少,如何编写一个 SQL 查询:

  1. 将auto_increment 值更改为最大值(当前值)+ 1
  2. 返回新的auto_increment 值?

我知道如何编写 1 和 2 部分,但我可以将它们放在同一个查询中吗?

如果不可能:

如何“选择”(返回)auto_increment 值或auto_increment 值 + 1?

【问题讨论】:

  • 您应该始终指定您正在使用的数据库系统,例如在这种情况下是 MySQL。
  • 抱歉,感谢您告诉我。

标签: mysql auto-increment


【解决方案1】:

重新编号会造成混乱。现有报告将引用记录 99,但如果系统重新编号,它可能会将该记录重新编号为 98,现在所有报告(和填充的 UI)都是错误的。一旦分配了唯一 ID,它就必须保持不变。

将 ID 字段用于除简单唯一编号之外的任何内容都会有问题。要求“无间隙”与能够删除的要求完全不一致。也许您可以将记录标记为已删除而不是删除它们。那么就真的没有缝隙了。假设您正在制作带编号的发票:您将拥有一张带有该编号的零值已取消发票,而不是删除它。

【讨论】:

    【解决方案2】:

    正如 djna 在她/他的回答中所说,以这种方式更改数据库表不是一个好习惯,如果您一直在选择正确的方案和数据,也没有必要这样做类型。顺便说一下你的问题:

    我有一个带有 auto_increment 字段的表,有时行会被删除,因此 auto_increment 会留下空白。有什么办法可以避免吗?

    1. 如果您的表在其自动增量列中有太多间隙,可能是由于太多测试INSERT 查询的结果
    2. 如果您想通过消除间隙来防止过多的 id 值
    3. 如果id 列只是一个计数器,与数据库中的任何其他列都没有关系

    ,这可能是您(或任何其他正在寻找此类东西的人)正在寻找的东西:

    解决方案

    1. 删除原来的id列
    2. 使用auto_increment on 再次添加

    但如果您只想将auto_increment 重置为第一个可用值:

    ALTER TABLE `table_name` AUTO_INCREMENT=1
    

    【讨论】:

      【解决方案3】:

      我通常同意此页面上的智者(以及duplicate 问题)建议不要重复使用自动递增的 ID。这是一个很好的建议,但我认为提出这个问题的对错不应该由我们来决定,让我们假设开发人员知道他们想要做什么以及为什么。

      答案是,正如 Travis J 所说,您可以通过在插入语句中包含 id 列并分配您想要的特定值来重用自动增量 id。

      这里有一点需要使用扳手:MySQL 本身(至少 5.6 InnoDB)将在以下情况下重用自动增量 ID:

      • 删除具有最高自动增量 ID 的任意行数
      • 停止和启动 MySQL
      • 插入新行

      插入的行的 id 计算为 max(id)+1,它确实不从被删除的 id 继续。

      【讨论】:

        【解决方案4】:

        即使在 autoinc 表中,也有一种手动插入 id 的方法。您所要做的就是找出丢失的 ID。

        但是,不要这样做。如果您的数据库是关系型的,那可能会非常危险。删除的 id 可能在其他地方使用过。删除后,它不会造成太大问题,也许它会孤立记录。如果被替换,它会带来一个巨大的问题,因为会出现错误的关系。

        假设我有一张汽车桌和一张人桌

        car
        carid
        ownerid
        name
        
        person
        personid
        name
        

        还有一些简单的数据

        car
        1 1 Van
        2 1 Truck
        3 2 Car
        4 3 Ferrari
        5 4 Pinto
        
        person
        1 Mike
        2 Joe
        3 John
        4 Steve
        

        现在我删除了 John。

        person
        1 Mike
        2 Joe
        4 Steve
        

        如果我在表中添加了一个新人 Jim,并且他得到了一个填补空白的 id,那么他最终会得到 id 3

        1 Mike
        2 Joe
        3 Jim
        4 Steve
        

        按关系来说,他是法拉利的车主。

        【讨论】:

          【解决方案5】:

          不确定这是否会有所帮助,但在 sql server 中,您可以重新设定身份字段。似乎在 mySql 中有一个 ALTER TABLE 语句来实现这一点。例如,将 id 设置为在 59446 处继续。

          ALTER TABLE table_name AUTO_INCREMENT = 59446; 
          

          我想你应该可以结合一个查询来获取auto_increment字段的最大值,然后根据需要使用alter table进行更新。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-12-09
            • 2013-04-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-30
            • 2011-12-13
            相关资源
            最近更新 更多