【问题标题】:Primary Key Value Not Incrementing Correctly主键值未正确递增
【发布时间】:2014-10-02 04:33:37
【问题描述】:

我有一个 django 模型,它的 id 开始奇怪地增加。

该列的 postgres 定义(从 Django 模型生成):

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 跳过,然后在 2 个对象中跳到 8378,然后在 3 个对象中跳到 97xx它跃升至 14k。

【问题讨论】:

    标签: django postgresql auto-increment


    【解决方案1】:

    从序列中获取默认值的序列列从不保证无缝。保证它们是唯一升序(如定义)和并发使用安全
    如果从序列中抽取了一个数字的事务被回滚,这个数字就被烧掉了,不再被使用……Per documentation:

    注意:因为 smallserialserialbigserial 是使用实现的 序列,值序列中可能存在“漏洞”或间隙 即使没有删除任何行,它也会出现在列中。一个值 即使有一行,从序列分配的仍然“用完” 包含该值永远不会成功插入到表中 柱子。例如,如果插入事务回滚,则可能会发生这种情况。 详情请参阅Section 9.16 中的nextval()

    如果您看到像427 -> 4357 这样的大间隙,则表明存在严重问题。要么是其他列(或任何进程)从同一序列中绘制,要么您的应用程序逻辑有问题,以某种方式烧毁了很多序列 ID。

    典型的候选是循环出错或从未提交的事务。

    【讨论】:

      猜你喜欢
      • 2017-01-09
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      相关资源
      最近更新 更多