20

我无法为自己想象一个好的答案,所以我想在这里问它。在我的脑海中,我总是想知道如果AUTO INCREMENT PRIMARY ID我的MySQL表中的列耗尽会发生什么?

例如,我有一个有两列的表。ID ( auto increment, primary, BIGINT unsigned) 和DESC ( ) VARCHAR 255。我知道肯定BIGINT很多,但它可以达到它的极限。如果ID达到其限制,我该如何处理?我需要另一台服务器吗?如果那么我该如何同步它?这是正确的方法吗?有什么见解的朋友。

4

4 回答 4

54

它不会用完。

最大 bigint 是 9223372036854775807 。以 1000 次插入/秒的速度,这相当于 106751991167 天。如果我的数学是对的,将近 3 亿年。

即使你将它分割出来,使用偏移量,比如 100 个服务器每个都有一个专用的值子范围 ( x*100+0... x*100+99),你也不会用完。10,000 台机器每秒执行 100,000 次插入可能会在大约三个世纪内让您到达那里。当然,这比数百年来稳定的纽约证券交易所每秒的交易量还要多……

如果您确实超过了生成键的数据类型大小限制,新插入将失败。在 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 在评论中指出的那样,您永远不会存储那么多数据。这只是对交易率极高的高流失率表的关注。在这些表中,应用程序只需要能够应对键被重置为零、条目重新编号或其他应对策略。不过,老实说,即使是高流量的消息队列表也不会达到顶峰。

看:

说真的,即使您构建了下一个 Gootwitfacegram,在您第三次重写应用程序的使用日期之前,这也不会成为问题......

于 2012-10-30T05:14:57.847 回答
14

大 int 是2^63或大约10^19。数据库基准在几年前曾经风靡一时,使用标准化的TPC-C 基准

如您所见,关系数据库的最快关系得分为30,000,000(每分钟 3x10^7 个事务)。请记住,配置文件将包含大量读取,并且同一系统不太可能每分钟写入30,000,000行。

假设是这样,您将需要大约3x10^11分钟来耗尽 BigInt。在我们理解的时间测量中,这大约是600 万年

ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

如果您确实用完了,您将收到上述错误消息,然后转到 Guid 获取主键。 2^128地球上的数字位比那个数字少(万亿倍)。

于 2012-10-30T05:33:06.860 回答
2

大型数据集不使用递增数字作为键。不仅因为你有一个隐含的上限,而且当你有多个服务器时也会产生问题;因为您冒着拥有重复主键的风险,因为它们是增量的。

当你在 MySQL 上达到这个限制时,你会得到一个像这样的神秘错误:

Error: Duplicate entry '0' for key 1

最好使用您生成的唯一 ID 或其他序列。MySQL 不支持序列,但 postgresql 支持。

于 2012-10-30T05:16:01.697 回答
2

一旦 Autoincrement 达到字段大小的限制,INSERT 将生成错误。

实际上,您将收到以下类型的错误:

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

于 2012-10-30T05:17:19.300 回答