我有一个django模型,开始让它的ID增加奇怪。
列的postgres定义(从Django Model生成):
id | integer | not null default nextval('billing_invoice_id_seq'::regclass)
tpg=> SELECT MAX(id) FROM billing_invoice;
max
-------
16260
然后我通过django admin创建了一条新记录:
tpg=> SELECT MAX(id) FROM billing_invoice;
max
-------
17223
tpg=> SELECT nextval('billing_invoice_id_seq');
nextval
---------
17224
然后我创建了一条新记录,该记录跳过17224值并插入主键为17225:
tpg=> SELECT nextval('billing_invoice_id_seq');
nextval
---------
17226
有谁知道为什么会这样?该应用程序此时并不在意,因为ID仍然在增加,但是在过去的几个新对象中,PK已经从427跳过了 - > 4357在一个插入中然后到8378在2个对象中它跳转到97xx然后在3个对象中它跳到14k。
答案 0 :(得分:4)
从序列中取默认值的串行列 从不 保证无间隙。它们保证唯一和升序(定义)和安全并发使用。
如果回滚了从序列中抽取数字的事务,则该号码将被烧毁而不再使用... Per documentation:
注意:由于使用了
smallserial
,serial
和bigserial
序列,可能有"孔"或者值的序列中的间隙 即使没有删除任何行,它也会显示在列中。一个值 从序列中分配的仍然是“用完了”#34;即使一排 包含该值永远不会成功插入表中 柱。例如,如果插入事务回滚,则可能发生这种情况。 有关详细信息,请参阅Section 9.16中的nextval()
。
如果您发现427 -> 4357
之类的大差距,则表明存在严重问题。其他一些列(或任何进程)正在从相同的序列中绘制,或者您的应用程序逻辑出现问题,以某种方式刻录了大量序列ID。
典型的候选人是循环错误或从未提交过的交易。