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

Oli*_*Oli 3 django postgresql auto-increment

Booking在Django中有一个模型,它的ID是idDjango创建的内置列.以下是它在Postgres中查看数据库级别的方式:

integer   not null default nextval('bookings_booking_id_seq'::regclass)
Run Code Online (Sandbox Code Playgroud)

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

..2, ..3, ..4, ..6, ..8, ..9
Run Code Online (Sandbox Code Playgroud)

他们担心系统正在丢弃或删除预订.在哪里..5..7?我们[实际上]记录了可以删除预订的所有内容,因此我非常有信心这不是系统问题.程序员的直觉也告诉我不要期望Auto-ID的连续性,但单凭直觉对于向客户解释是不够的.

是否存在技术原因Postgres在分配这些ID时会跳过数字?

Say*_*yse 6

来自postgres文档:

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

还有来自的文档 nextval

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