【问题标题】:MySQL skipping auto_increment valuesMySQL 跳过 auto_increment 值
【发布时间】:2020-03-21 15:30:23
【问题描述】:

在我的用户表中只有 3 个字段

id (primary key, auto increment), 
username (not null, unique) and 
password(not null). 

当我尝试插入具有值“test”和“123”的行时,我得到 1 作为主键,然后我再次尝试使用相同的值,我得到了键“username”的重复条目,然后我尝试使用“test1”和“123”,我得到 3 作为主键,2 被跳过,为什么它会显示这种行为。

MySQL 版本为 5.7.27。

【问题讨论】:

  • 请提供表格的定义。如果所有约束都正常并且 INSERT 失败,则可以使用 REPLACE 而不是 INSERT

标签: mysql sql database database-design auto-increment


【解决方案1】:

这是documented behavior

“丢失”的自动增量值和序列间隙

在所有锁定模式(0、1 和 2)中,如果生成自增值的事务回滚,则这些自增值将“丢失”。一旦为自增列生成了一个值,它就不能回滚,无论“INSERT-like”语句是否完成,以及包含的事务是否回滚。这种丢失的值不会被重用。因此,存储在表的 AUTO_INCREMENT 列中的值可能存在间隙。

在您的用例中,在检查 username 的唯一约束之前,会为 auto_increment 分配一个新值。然后约束检查失败,事务回滚,在序列中留下空隙。

还有许多其他情况会导致 auto_increment 序列出现间隙(例如,使用 INSERT ... IGNOREINSERT ... ON DUPLICATE KEY 语法时),这些情况本质上与事务的隐式或显式回滚有关。

底线:不要假设 aut_increment 键是连续的。保证的是唯一性,并且在某种程度上,数量不断增加。

【讨论】:

  • @Sony,要添加到 GMB 提到的底线,也不要尝试 "fixing" 你的 auto_increment 是顺序的,这也是一个很大的不,因为然后可能会发生诸如难以调试竞争条件之类的错误/问题..
猜你喜欢
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 2018-03-19
  • 2016-07-26
  • 2021-12-04
  • 1970-01-01
  • 2013-12-22
相关资源
最近更新 更多