主键值未正确递增

时间:2014-08-08 16:17:55

标签: django postgresql auto-increment

我有一个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。

1 个答案:

答案 0 :(得分:4)

从序列中取默认值的串行列 从不 保证无间隙。它们保证唯一升序(定义)和安全并发使用
如果回滚了从序列中抽取数字的事务,则该号码将被烧毁而不再使用... Per documentation:

  

注意:由于使用了smallserialserialbigserial   序列,可能有"孔"或者值的序列中的间隙   即使没有删除任何行,它也会显示在列中。一个值   从序列中分配的仍然是“用完了”#34;即使一排   包含该值永远不会成功插入表中   柱。例如,如果插入事务回滚,则可能发生这种情况。   有关详细信息,请参阅Section 9.16中的nextval()

如果您发现427 -> 4357之类的大差距,则表明存在严重问题。其他一些列(或任何进程)正在从相同的序列中绘制,或者您的应用程序逻辑出现问题,以某种方式刻录了大量序列ID。

典型的候选人是循环错误或从未提交过的交易。