虽然这看起来是一个微不足道的要求,但实际上并非如此。
您可能认为自动增量列或序列将提供无间隙系列,但事实并非如此:插入期间遇到的任何回滚或错误都会在列中留下间隙。永远不能相信序列是无间隙的。
在多用户环境中,为确保获得无间隙的列,您需要序列化提供数字的过程。实现这一目标的两种主要方法是:
- 序列化插入(在 Oracle 中带有
LOCK TABLE IN EXCLUSIVE MODE
)。正如您所料,这不会很好地扩展。
推迟实际编号。您将插入所需列设置为空的新行。然后将发出后续的单独流程:
UPDATE my_table
SET gap_less_id = (SELECT MAX(gap_less_id) FROM my_table) + rownum
WHERE gap_less_id IS NULL;
您需要确保此后续作业在任何时候仅运行一次(例如参见另一个 SO:PL/SQL 过程的同步。如何保证每次只执行一个过程)。
这当然意味着赋予该列的值在提交后会延迟,尽管为扩展能力付出的代价可能很小。
我的第一个建议是真正确保无间隙要求不是虚假的。id
如果您的员工表中缺少一个,这真的很重要吗?可能不是,这只是一个用于唯一标识行的主键。您可以使用其他工具来计算行数,或按插入时间对行进行排名。在这种情况下,使用带有 的序列CACHE 0
,您不应该丢失太多的 ID。
如果这是一个真实的需求,比如法律需要,那么问问自己是否可以使用另一列作为主键。如果您可以接受将编号推迟到提交之后,您可以使用至少允许并发插入的第二种方法。