为什么在违反唯一键约束而不是主键约束时 MySQL 中存在自动递增间隙?

Why are there auto increment gaps in MySQL when violating a unique key constraint, but not a primary key constraint?

我了解在 MySQL 中使用 INSERT ... ON DUPLICATE KEY UPDATE 时,插入失败时会出现自动递增间隙。但是——我注意到只有在违反唯一键约束时才会出现间隙。如果主键约束失败,则不会出现自增间隙。

两者不同的原因是什么?

谢谢!

如果自动递增字段是主键,那么仅当您在插入语句中将自动递增字段的值显式设置为该字段中已经存在的值时,才会在主键中发生重复(为什么要这样做这超出了我的范围)。

正如 mysql 关于 using auto increment 的文档所说:

When you insert any other value into an AUTO_INCREMENT column, the column is set to that value and the sequence is reset so that the next automatically generated value follows sequentially from the largest column value.

关键是,在这种情况下 mysql 不会尝试为自动递增列生成值,而是会使用插入中指定的值。此外,序列也重置为字段中的最大值,因此下一次插入不会有任何间隙。

但是,如果在您尝试插入时另一个唯一索引约束失败,则 mysql 已经为自动递增字段生成了值,因此在自动递增序列中会产生间隙。

只有当您没有为 AI 列指定值时,才会生成新的自动增量值。

mysql> create table MyTable (id int auto_increment primary key, x int, unique key(x));
mysql> insert into MyTable values (1, 100), (2, 200);

mysql> insert into MyTable (id) values (2);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

在这个例子中,只有当我在我的 INSERT 中指定一个值时,我才能创建一个重复的 id 值。在这种情况下,它会跳过分配新的 AI 值。

而如果我创建了一个与我的辅助唯一列冲突的重复值,我可能不会为该 ID 指定一个特定值。这将导致 AI 生成新值,但最终 INSERT 失败,因为辅助列中存在重复,并且生成的 AI 值丢失。

mysql> insert into MyTable (x) values (200);
ERROR 1062 (23000): Duplicate entry '200' for key 'x'