当我耗尽bigint生成的密钥时会发生什么?怎么处理?

fis*_*ker 18 mysql sql postgresql

我无法为自己想象一个好的答案,所以我想在这里问一下.在我看来,我总是想知道如果AUTO INCREMENT PRIMARY ID我的MySQL表中的列用尽了会发生什么?

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

Cra*_*ger 45

它不会用完.

最大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)
Run Code Online (Sandbox Code Playgroud)

对于普通人来说,serial你会得到一个不同的错误,因为sequence它总是64位,所以你将达到你必须改变键类型bigint或得到如下错误的点:

regress=# SELECT setval('serialtest_id_seq', 2147483647);
regress=# INSERT INTO serialtest (dummy) VALUES ('ham');
ERROR:  integer out of range
Run Code Online (Sandbox Code Playgroud)

如果您确实认为您的网站可能会在应用程序中的bigint上达到限制,则可以使用复合键 - 比如说(shard_id,subkey) - 或者使用uuid键.

尝试在新应用程序中处理此问题是过早优化.说真的,从新的应用程序到这种增长,你会使用相同的架构吗?还是数据库引擎?甚至代码库?

您可能还担心GUID键控系统中的GUID冲突.毕竟,生日悖论意味着GUID冲突比你想象的更可能 - 令人难以置信的是,极不可能.

此外,正如Barry Brown在评论中指出的那样,你永远不会存储那么多数据.这只是高流失表的一个问题,具有极高的交易率.在这些表格中,应用程序只需要能够处理重置为零的密钥,重新编号的条目或其他应对策略.但老实说,即使是高流量的消息队列表也不会出类拔萃.

看到:

说真的,即使你构建了下一个Gootwitfacegram,在你的第三个应用程序重写的使用期限过去之前,这也不会有问题......

  • 那些9223372036854775807 bigints将需要67,108,863太字节存储.有那么多的磁盘空间? (11认同)
  • @BurhanKhalid绝对是一切都在踢我的路上,问题是你需要踢多远?文件系统有大小限制(尽管其中一些限制是exabytes),操作系统对可以安装的文件系统数量,可以解决的磁盘数等有限制.时钟的上限可以表示.理智的方法是踢足够远,以至于其他限制首先生效,然后停止关怀.尝试提出完美的解决方案,让您的应用程序在10,000年内保持不变,这一点毫无意义. (5认同)
  • 问题不在于它是否耗尽,问题是如何设计表以避免增量主键的任意限制. (2认同)

M A*_*ifi 12

Big 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
Run Code Online (Sandbox Code Playgroud)

如果确实用完了,您将收到上述错误消息,并转到Guid获取主键. 2 ^ 128,地球上的数字位数少于该数字(以千万亿倍为单位).