考虑一个带有自动增量列的简单表,如下所示:
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问题一样,我想做好准备。
答案 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的数量),那么使用SMALLINT
和INSERT
s就可以很容易地发生。想象一下,您正在更改代码并测试您的数据是否正确插入。突然你的应用程序退出处理上面的错误。您将更改回滚到已知的良好代码,但错误不会消失......非常令人沮丧。
答案 2 :(得分:2)
不了解MySQL,但在Postgresql的情况下,您可以指定序列是否为CYCLE / NO CYCLE。如果使用CYCLE选项创建,它将再次返回到1(或最小值),并将为重复键抛出错误。