它不会用完。
最大 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,在您第三次重写应用程序的使用日期之前,这也不会成为问题......