4

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

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

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

如果这是不可能的:

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

4

5 回答 5

9

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

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

于 2009-12-01T07:53:01.487 回答
1

即使在 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

现在我删除人约翰。

person
1 Mike
2 Joe
4 Steve

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

1 Mike
2 Joe
3 Jim
4 Steve

并且通过关系,将是法拉利的所有者。

于 2013-05-07T21:37:55.627 回答
1

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

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

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

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

插入的行将有一个计算为 max(id)+1 的 id,它不会被删除的 id 继续。

于 2015-07-01T09:30:32.820 回答
0

正如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
于 2015-12-25T06:34:06.683 回答
-1

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

ALTER TABLE table_name AUTO_INCREMENT = 59446; 

我认为您应该能够结合查询来获取 auto_increment 字段的最大值,然后根据需要使用 alter table 进行更新。

于 2009-12-01T07:50:48.747 回答