如何在postgres中的id字段上实现一个简单的主键

时间:2017-10-05 00:36:49

标签: sql postgresql primary-key sql-insert

我一直在挖掘堆栈流,似乎很奇怪像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

其中索引之间插入失败。该应用程序工作,但我发现这很烦人。建议?

1 个答案:

答案 0 :(得分:2)

基于@Gordon Linoff的评论,这种行为是可扩展性的重要组成部分,允许数据库跨连接并发处理插入。

没有它,为了实现无间隙方案,每个事务必须完整或完全失败才能将下一个ID分配给任何表。使用SEQUENCE概念的DB将无法缓存值块,这意味着序列号的每次分配(无论出于何种原因)都需要锁定,而锁定又可能阻塞。

在这两种情况下,为了保证下一个值,数据库无法继续,直到没有其他待处理的状态。您基本上最终会得到一个巨大的序列化插入队列,并且它们的数据库不会扩展,至少对于插入而言。

所有数据库都是这样工作的,这就是原因所在。我希望这有助于你理解,即使你仍然觉得它很烦人。唯一真正的解决方法是在事件发生后以大批量或SELECT分配一个真实的序列号,但你通常会发现它很少,如果值得做的话。