一尘不染

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

mysql

我无法想象自己对此有一个很好的答案,所以我想到了在这里提问。在我看来,我一直想知道如果AUTO INCREMENT PRIMARY ID我的
MySQL 表中的列用完了会怎样?

举例来说,我有一个包含两列的表。的 IDauto increment, primary, BIGINT unsigned)和
DESCVARCHAR 255)。我当然知道BIGINT很多,但是可以达到极限。如何处理场景,其中 的情况下,ID
达到它的极限?我需要其他服务器吗?如果可以,该如何同步呢?这是正确的方法吗?任何有识之士的朋友。


阅读 302

收藏
2020-05-17

共1个答案

一尘不染

它不会用完。

最大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,也要等到第三个应用程序重写的使用日期之前,这才不会成为问题。

2020-05-17