我一直在挖掘堆栈流,似乎很奇怪像postgres这样强大的数据库管理软件没有一种简单的方法来提供这个。
我到目前为止最好的解决方案是
id serial primary key,
,
但是如果你想做
INSERT VALUE ON CONFLICT DO NOTHING
(我添加了最后一部分b / c postgres不能INSERT OR IGNORE
),即使插入失败,序列也会依赖。
所以你得到的表可能看起来像:
id | name
1 | amy
5 | bob
12 | john
104 | thomas
其中索引之间插入失败。该应用程序工作,但我发现这很烦人。建议?
答案 0 :(得分:2)
基于@Gordon Linoff的评论,这种行为是可扩展性的重要组成部分,允许数据库跨连接并发处理插入。
没有它,为了实现无间隙方案,每个事务必须完整或完全失败才能将下一个ID分配给任何表。使用SEQUENCE
概念的DB将无法缓存值块,这意味着序列号的每次分配(无论出于何种原因)都需要锁定,而锁定又可能阻塞。
在这两种情况下,为了保证下一个值,数据库无法继续,直到没有其他待处理的状态。您基本上最终会得到一个巨大的序列化插入队列,并且它们的数据库不会扩展,至少对于插入而言。
所有数据库都是这样工作的,这就是原因所在。我希望这有助于你理解,即使你仍然觉得它很烦人。唯一真正的解决方法是在事件发生后以大批量或SELECT
分配一个真实的序列号,但你通常会发现它很少,如果值得做的话。