自动递增列用完后会发生什么?

时间:2008-12-12 07:28:08

标签: mysql database-design

考虑一个带有自动增量列的简单表,如下所示:

CREATE TABLE foo 
(
  `fooid` bigint unsigned NOT NULL auto_increment,
   ....snipped.... other columns
  PRIMARY KEY (`fooid`)
) 
ENGINE=InnoDB AUTO_INCREMENT=10

如何重新设计这个以便我们不会达到bigint数据类型的最大值? 无符号范围是0到18446744073709551615。 我不知道要达到18446744073709551615需要多长时间,但是就像Y2K问题一样,我想做好准备。

3 个答案:

答案 0 :(得分:57)

假设您每毫秒插入一行。

18446744073709551615 millseconds = 18446744073709552秒= 307445734561826分钟= 5124095576030小时= 213503982335天= 584942417年

所以不像Y2K问题那样

您可以每毫秒插入百万行,并且500多年后仍然可以。

换句话说:不要担心。

答案 1 :(得分:18)

根据您使用的SQL mode,当AUTO_INCREMENT数字列的值超出范围时,MySQL会执行以下两项操作之一。在任何一种情况下都会出错,但出于不同的原因。

严格模式中,MySQL拒绝超出范围的值,抛出无效值错误,INSERT失败。在默认的非严格模式中,MySQL将值减少到数据类型允许的最高值,并执行INSERT。但INSERT失败,因为AUTO_INCREMENT属性已导致所有可能的值已被使用,并且您收到此错误(无符号SMALLINT示例):

MySQL said:

#1062 - Duplicate entry '65535' for key 1

对于此处的BIGINT示例,将“65535”替换为18 quintillion,尽管生产数据库中不会发生此错误。

但是如果你在应用程序的生命周期中低估了可能的键值(TINYINT s的数量),那么使用SMALLINTINSERT s就可以很容易地发生。想象一下,您正在更改代码并测试您的数据是否正确插入。突然你的应用程序退出处理上面的错误。您将更改回滚到已知的良好代码,但错误不会消失......非常令人沮丧。

答案 2 :(得分:2)

不了解MySQL,但在Postgresql的情况下,您可以指定序列是否为CYCLE / NO CYCLE。如果使用CYCLE选项创建,它将再次返回到1(或最小值),并将为重复键抛出错误。