我自己想不出一个好的答案,所以我想在这里问它。在我的脑海中,我一直在想,如果我的MySQL表中的AUTO INCREMENT PRIMARY ID
列用完了,会发生什么?
例如,我有一个表,它有两列。一个ID(auto increment, primary, BIGINT unsigned
)和DESC情况下ID达到其极限的情况?我需要另一台服务器吗?如果是,我该如何同步?这是正确的路吗?任何见解的朋友。
它不会用完。
最大bigint为9223372036854775807。每秒1000次插入,相当于106751991167天。如果我的数学正确的话,差不多3亿年了。
即使使用偏移量进行分区,比如说100台服务器都有一个专用的值子范围(x*100+0
…x*100+99
),也不会用完。10000台机器每秒插入100000个插件,可能会在大约三个世纪内实现这一目标。当然,这比纽约证券交易所数百年来每秒的交易量还要多。。。
如果超过生成密钥的数据类型大小限制,则新插入将失败。在PostgreSQL中(因为你已经标记了这个PostgreSQL),使用bigserial
,你会看到:
CREATE TABLE bigserialtest ( id bigserial primary key, dummy text );
SELECT setval('bigserialtest_id_seq', 9223372036854775807);
INSERT INTO bigserialtest ( dummy ) VALUES ('spam');
ERROR: nextval: reached maximum value of sequence "bigserialtest_id_seq" (9223372036854775807)
对于普通的serial
,你会得到一个不同的错误,因为sequence
总是64位的,所以你必须将密钥类型更改为bigint
,或者得到一个错误,比如:
regress=# SELECT setval('serialtest_id_seq', 2147483647);
regress=# INSERT INTO serialtest (dummy) VALUES ('ham');
ERROR: integer out of range
如果你真的相信你的站点有可能达到应用程序中bigint的限制,你可以使用一个复合密钥,比如(shard_id,subkey),或者一个uuid密钥。
试图在新的应用程序中处理此问题是过早的优化。说真的,从一个新的应用程序到这种增长,你会使用相同的模式吗?还是数据库引擎?甚至是代码库?
您还可以担心GUID键控系统中的GUID冲突。毕竟,生日悖论意味着GUID冲突的可能性比你想象的要大——难以置信,难以置信。
此外,正如Barry Brown在评论中指出的那样,你永远不会存储那么多数据。这只是高流失率和极高交易率的表所关心的问题。在这些表中,应用程序只需要能够处理键重置为零、条目重新编号或其他应对策略。不过,老实说,即使是高流量的消息队列表也不会达到最高流量。
参见:
- 此IBM关于串行耗尽的信息
- 最近关于此主题的博客文章
说真的,即使你构建了下一个谷歌脸书,这也不会成为问题,直到你的第三个应用程序重写的使用日期。。。
大int为2^63或大约10^19。数据库基准测试在几年前风靡一时,使用标准化的TPC-C基准
正如您所看到的,关系数据库的最快关系得分为3000000(每分钟3x10^7个事务)。请记住,概要文件将包括大量读取,并且同一系统不太可能每分钟写入3000000行。
假设是这样,您将需要大约3x10^11分钟来耗尽BigInt。在时间测量中,我们可以理解,这大约是600万年
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
如果您确实用完了,您将收到上面的错误消息,并转到主键的Guid2^128,地球上的数字比特比这个数字少(数万亿)。
一旦Autoincrement达到字段大小的限制,INSERTs将生成一个错误。
在实践中,你会得到以下类型的错误:
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
欲了解更多信息,请访问:
http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
大型数据集不使用递增数字作为键。这不仅是因为你有一个隐含的上限,而且当你有多个服务器时也会产生问题;因为主键是增量的,所以存在重复主键的风险。
当你在MySQL上达到这个限制时,你会得到这样一个神秘的错误:
Error: Duplicate entry '0' for key 1
最好使用您生成的唯一id或其他序列。MySQL不支持序列,但postgresql支持。