它不会用完。
最大 bigint 为 9223372036854775807 。如果每秒插入 1000 次,则相当于 106751991167 天。如果我的数学没错的话,差不多有三亿年了。
即使您将其分区,使用偏移量,其中 100 个服务器每个都有一个专用的值子范围(x*100+0
... x*100+99
),你不会用完的。 10,000 台机器每秒执行 100,000 次插入可能需要大约三个世纪才能实现这一目标。当然,这比纽约证券交易所数百年来每秒的交易量还要多……
If you do超过生成键的数据类型大小限制,新插入将失败。在 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 冲突的可能性比您想象的要大 https://stackoverflow.com/questions/184869/are-guid-collisions-possible- 难以置信,极其不可能。
此外,正如巴里·布朗在评论中指出的那样,您永远不会存储那么多数据。这只是对于交易率高得离谱的高客户流失表的担忧。在这些表中,应用程序只需要能够应对密钥重置为零、条目重新编号或其他应对策略。但老实说,即使是高流量的消息队列表也不会达到顶峰。
See:
- IBM 关于串行耗尽的信息 http://publib.boulder.ibm.com/infocenter/idshelp/v117/index.jsp?topic=%2Fcom.ibm.ddi.doc%2Fids_ddi_194.htm
- 最近关于此主题的博客文章 http://improve.dk/archive/2012/02/20/stop-worrying-about-exhausting-bigints.aspx
说真的,即使您构建了下一个 Gootwitfacegram,直到过了第三次应用程序重写的使用日期之前,这都不会成为问题......