问题
我们正在使用Java和PostgreSQL构建一个Web应用程序。它相当大且成功,并且应该能够继续运行至少几年。
不幸的是,在设计过程的早期阶段,我们(也就是我)犯了一个严重的错误:所有数据库ID都是从一个共享序列中分配的整数。
Java的最大int值是2^31-1,约为20亿。对于PostgreSQL的整数类型,情况也是如此。该系统目前每天会使用约10k个ID,并且随着我们获得新用户,速度正在上升。
有一天,ID将耗尽并溢出。
问题
我们正在寻找解决方案。让我们首先排除的那个显而易见的解决方案:切换到Java的long
和Postgres的bigint
是一个干净的解决方案,但它需要大量工作。我们需要尽可能地推迟它。
到目前为止,我们想到的一些解决方案:
- 不要为所有内容使用一个序列,而是为每个表分配自己的序列。
- 优点:这样可以使我们获得多达N倍的时间,其中N是表的数量。
- 缺点:我们喜欢每行都有唯一ID的事实。
- 停止为某些表使用序列ID。例如,具有客户事件的表实际上不需要ID:
customer,timestamp
是一个完全有效的主键。- 优点:我们最大的ID消耗量可以通过此方式改变。
- 缺点:需要做出相当大的努力。
- 停止浪费IDs用于空记录。这在某些子表中发生,例如客户联系信息。始终存在该记录可以使代码更简单,但这意味着许多客户存储了一个空的联系信息记录。
- 优点:我们最大的ID消耗量可以通过此方式修复。
- 缺点:我们失去了代码的简洁性。
- 每个新表都必须使用
long
/bigint
和新序列。- 优点:至少我们不会让它变得更糟。
- 缺点:与其余代码的接触面将很丑陋。
在这些限制条件下,还有哪些方法可以推迟ID的耗尽?