当违反唯一键约束而不是主键约束时,为什么MySQL中存在自动增量空白?

时间:2018-01-02 21:40:41

标签: mysql auto-increment on-duplicate-key

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

两者之间存在差异的原因是什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

如果自动增量字段是主键,那么只有在将insert语句中的自动增量字段值显式设置为该字段中已存在的值时,主键中的重复才会发生(为什么要这样做呢?超越我)。

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

  

当您将任何其他值插入AUTO_INCREMENT列时,该列将设置为该值并重置序列,以便下一个自动生成的值按顺序从最大列值开始。

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

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

答案 1 :(得分:1)

仅当您没有为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'