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

How to implement a simple primary key on an id field in postgres

我一直在研究 stackover flow,似乎很奇怪,像 postgres 这样强大的数据库管理软件没有提供这种功能的简单方法。

我目前最好的解决方案是

id serial primary key,,

但如果您想

INSERT VALUE ON CONFLICT DO NOTHING

(我正在添加最后一部分 b/c postgres 无法做到 INSERT OR IGNORE),即使插入失败,序列仍将继续计算。

所以您得到的 table 可能类似于:

id | name
1 | amy
5 | bob
12 | john
104 | thomas

索引之间的插入失败。该应用程序有效,但我觉得这很烦人。建议?

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

如果没有它,要实现无间隙场景,每个事务都必须完成或全部失败,然后才能将下一个 ID 分配给任何 table。使用 SEQUENCE 概念的数据库将无法缓存值块,这意味着每次分配序列号(无论出于何种原因)都需要一个锁,而锁又可能会阻塞。

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

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