关于插入时的mysql自动增量行为

时间:2014-09-02 22:46:26

标签: mysql sql

我将使用mysql进行项目。我有一些主键作为一个自动递增的整数表(称之为id)。

当我插入一些无法插入的东西时(例如,一个唯一的字段ip,你插入相同的ip)它不会让你插入(这是好的!)但是,然后,id增加...这是不正确,因为我试图插入,但我不能。

Is this a normal behavior? 

我怎样才能确保id只会在" okay"插入值?

谢谢

1 个答案:

答案 0 :(得分:4)

是的,这是正常行为。从MySQL 5.1开始,InnoDB会尽快释放表的auto-inc锁,以允许并发线程在不等待你的线程的情况下进行自己的插入。这意味着在已知INSERT成功之前释放auto-inc锁。因此,如果INSERT出现任何问题,它就无法“返回”自动递增的值,因为另一个线程可能已经分配了N + 1st auto-inc值,并且InnoDB不会跟踪除最近的auto之外的任何内容-inc值。

如果您有许多失败的插入,这会导致许多auto-inc值“丢失”的情况。例如,我帮助一个站点一直运行到最大签名INT值(2 31 -1),因为它们为成功插入的每一行跳过了1000-1500个值。所有这些都是因为其用户名栏上存在辅助UNIQUE约束。

你可以使InnoDB的行为与在MySQL 5.0中的行为相同,通过在my.cnf配置文件中设置innodb_auto_inc_lock_mode=0,让自动递增值在失败的INSERT上返回它们的增量。 请阅读http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-configurable.html了解详情。

但请注意,这限制了并发性,因为线程插入会将auto-inc保留更长时间。其他线程必须等待当前插入的线程完全成功才能获得auto-inc锁。如果您对同一个表的并发插入率很高,这可能会降低您的应用程序速度。

此外,主键序列中存在间隙是正常的,因为无论如何都会回滚某些事务,否则会删除行。永远不要假设您的主键值完全连续。它们旨在成为唯一值,而不是行号。