【问题标题】:Serial type column value getting non-sequential values序列类型列值获取非顺序值
【发布时间】:2021-12-24 22:22:30
【问题描述】:

我创建了一个序列列,如下所示:

CREATE TABLE public.table_name (
    "_id" serial4 NOT NULL,

我的假设是,该列将只有连续值,即1, 2, ..., n,其中n- 是表table_name 中的总行数。然而,事实并非如此:

SELECT max(_id), count(*) FROM public.table_name;

产量:

959132  111933

我知道我的假设很可能是一个错误的假设,但是请您告诉我实现我所追求的正确方法,最好还告诉我如何更新已经不连续的值以使它们连续。

Postgres 版本:

PostgreSQL 13.2 (Ubuntu 13.2-1.pgdg18.04+1)

【问题讨论】:

  • 您的假设确实不正确。但你所追求的也是不正确的。生成的主键值的唯一工作是唯一的。如果该值是1423673628-363 或其他值,则完全无关紧要。差距是预期的,没有什么可担心的。继续前进。
  • 如果从表格中间删除了一行,那么后面的所有行都应该改变它们的_id吗?
  • @τεκ 此表中没有删除,只有插入和更新。
  • 当一个 upsert 尝试插入时,它会调用 nextval() 消耗序列中的一个数字,即使存在冲突并且该行没有插入。
  • 它是连续的,只是不是无缝的。正如所指出的那样,serial 后面的序列生成器在事务执行时不会回滚,它只是继续前进。

标签: postgresql


【解决方案1】:

这很正常。如果

  • 您调用nextval(),但不使用该值

  • 您调用nextval() 并使用INSERT 中的值,但事务失败并回滚

  • 数据库崩溃

  • 您使用大于 1 的CACHE 创建了序列并关闭了数据库会话

人们通常想要一个“无间隙序列”,但大多数时候这并不是真正必要的。如果您在需要下一个值时使用UPDATE 的特殊计数器表,则可以得到它,但这将序列化所有需要值的事务。

没有办法在不严重影响性能的情况下获得无间隙序列。

您可以在我的article on that topic 中找到更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多