在我的项目中,我正在从一个数据库表中生成一个唯一的 ID,该 ID 采用属性“serial_key”的最大整数值,并将该数字加 1。它正在生成唯一索引以添加新的记录元组。
但是,当我在 Intranet 或 Internet 中的多台 PC 上部署应用程序时,这种机制失败了,它会立即在所有不同的机器上生成相同的唯一 ID。而且我在服务器中有大量数据,因此我必须管理相同的 id 模式,因为它是采用特定格式构建的。请建议如何解决这个问题。谢谢。
You can solve this by using an AUTO_INCREMENT
attribute on your serial_key
column. That way you don't have to worry about data collision. This is a common practice for primary keys.
为可移植的基于 DB 的密钥分配进行适当的“分配器表”设计:优先使用 Scott Ambler 被误导的“hi-lo”想法。
create table KEY_ALLOC (
SEQ varchar(32) not null,
NEXT bigint not null,
primary key (SEQ)
);
要分配下一个,比如说,20 个键(然后作为一个范围保存在服务器中并根据需要使用):
select NEXT from KEY_ALLOC where SEQ=?;
update KEY_ALLOC set NEXT=(old value+20) where SEQ=? and NEXT=(old value);
如果您可以提交此事务(使用重试来处理争用),您已经分配了 20 个密钥并可以根据需要分配它们。
该方案比从 Oracle 序列分配快 10 倍,并且在所有数据库中 100% 可移植。
与 Scott Ambler 的 hi-lo 想法不同,它将键空间视为连续的线性数字线——从中有效地分配可配置大小的小块。这些密钥对人类友好,不会浪费大块。Ambler 先生的想法是分配高 16 位或 32 位,并且需要丑陋的复合键或随着高字数的增加生成对人类不友好的大键值。
分配键的比较:
Linear_Chunk Hi_Lo
100 65536
101 65537
102 65538
.. server restart
120 131072
121 131073
122 131073
.. server restart
140 196608
猜猜开发人员或数据库管理员更容易使用哪些键。
实际上,我早在 90 年代就与他通信,向他建议了这个改进的方案,但他太固执和固执地承认使用线性数轴的优点。
您可以使用 HiLo 算法生成唯一密钥。它可以针对性能或连续键进行调整。如果您在所有客户端(我猜是 java 和 php)中实现它,您将在任意数量的键中获得唯一键(或您的数据库性能允许)。您也不会依赖于任何数据库,如果您调整它以提高吞吐量,您将不需要太多额外的数据库查询。
请参阅此SO-Answer。