为什么模型 ID 在 Postgres/Django 中并不总是下一个递增的数字?



我在Django中有一个Booking模型,它的ID是Django创建的内置id列。以下是它在Postgres:中数据库级别的表现

integer   not null default nextval('bookings_booking_id_seq'::regclass)

客户今天打来电话,担心这些数字似乎是连续的,但并不总是连续的。例如,序列为:

..2, ..3, ..4, ..6, ..8, ..9

他们担心系统会减少或删除预订。..5..7在哪里?我们[实际上]记录所有可以删除预订的,所以我很有信心这不是系统问题。程序员的直觉也教会了我不要指望Auto ID会有歧义,但单凭直觉还不足以向客户解释。

Postgres在分配这些ID时会跳过数字,这有技术原因吗?

来自postgres文档:

由于smallserial、serial和bigserial是使用序列实现的,因此即使从未删除任何行,列中出现的值序列中也可能存在"漏洞"或间隙。从序列中分配的值仍然"用完",即使包含该值的行从未成功插入表列。例如,如果插入事务回滚,则可能会发生这种情况。有关详细信息,请参见第9.16节中的nextval()。

以及nextval 的文档

为了避免阻塞从同一序列中获取数字的并发事务,永远不会回滚nextval操作;也就是说,一旦提取了一个值,它就被视为已使用,不会再次返回。即使周围的事务后来中止,或者调用查询最终没有使用该值,也是如此。例如,带有ON CONFLICT子句的INSERT将计算要插入的元组,包括执行任何所需的nextval调用,然后检测到任何会导致其遵循ON CONFLICT规则的冲突。这种情况会在赋值序列中留下未使用的"孔"。因此,PostgreSQL序列对象不能用于获得"无间隙"序列。

最新更新