4

我在 MySQL 中有一个使用 InnoDB 的表,并且有一个名为“id”的列。

所以我的问题是,每当我从表中删除最后一行然后插入一个新值时,新值就会在删除的 id 之后插入。

我的意思是假设我的 id 是 32,我想删除它,然后如果我在删除后插入一个新行,那么列 id 自动递增到 33。所以串行格式被破坏,即,id = 30,31,33没有32。

因此,当我在删除最后一列后插入时,请帮我分配 id 32 而不是 33。

4

4 回答 4

17

简短的回答:没有。

为什么?

  1. 这是不必要的工作。没关系,如果序列号有空缺。
  2. 如果您不希望这样,请不要使用 auto_increment。
  3. 别担心,我保证,如果您的列是 int 甚至 bigint 类型,您不会用完数字。
  4. 当您删除一行时,MySQL 不会自动减小自动增量值是有原因的。这些原因是
    • 破坏数据完整性的危险(想象多个用户执行删除或插入......可能会出现双重条目或更糟)
    • 使用主从复制或事务时可能会出现错误
    • 等等 ...

强烈建议你不要在这上面浪费时间!这真的非常容易出错。

于 2012-11-30T11:11:44.300 回答
4

您对关系数据库的工作方式有两个主要误解:

  1. 关系数据库中没有“最后一行”之类的东西。
  2. ID(假设这是您的主键)没有任何意义。是否为新行分配 33、35354 或 236532652632 无关紧要。这只是唯一标识该行的值。

不要依赖主键列中的连续值。

并且不要尝试这种max(id)+1方法。它根本无法在具有多个事务的系统中工作。

于 2012-11-30T11:12:54.107 回答
3

你应该停止与之抗争,即使SELECT max(id)在使用像 Innodb 这样的事务数据库引擎时使用也无法正确解决这个问题。

为什么你可能会问?想象一下,您有 2 个事务 A 和 B,它们几乎同时开始,都在执行 INSERT。第一个事务 A 需要新行id,它将从与该表关联的不可见序列中使用它(称为 AUTOINCREMENT 值),例如 21。另一个事务 B 将使用另一个连续值(例如 22) - 到目前为止一切顺利。

但是,如果事务 A 回滚怎么办?值 21 不能被重用,并且 22 已经被提交。如果有 10 次这样的交易呢?

并且max(id)可以为 A 和 B 分配相同的值,所以这也是无效的。

于 2012-11-30T11:13:50.420 回答
0

我想你的意思是“每当我从表中删除最后一行”,不是吗?

无论如何,这就是自动增量的工作原理。它是为了保持正确的数据关系。如果在另一个表中您使用已删除记录的 id,则在查询该 id 时获取错误而不是获取另一条记录更正确。

无论如何,您可以在这里看到如何获得字段中的第一个免费 ID。

于 2012-11-30T11:13:03.963 回答