PostgreSQL在每次更新时自动递增[英] PostgreSQL auto-increment increases on each update

本文是小编为大家收集整理的关于PostgreSQL在每次更新时自动递增的处理方法,想解了PostgreSQL在每次更新时自动递增的问题怎么解决?PostgreSQL在每次更新时自动递增问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

每次我执行 INSERT 或 UPSERT(ON CONFLICT UPDATE)时,每个表上的增量列都会按之前的更新数递增.

例如,如果我有这张桌子:

id int4
title text
description text
updated_at timestamp
created_at timestamp

然后运行这些查询:

INSERT INTO notifications (title, description) VALUES ('something', 'whatever'); // Generates increments ID=1

UPDATE notifications title='something else' WHERE id = 1; // Repeat this query 20 times with different values.

INSERT INTO notifications (title, description) VALUES ('something more', 'whatever again'); // Generates increments ID=22

这是一个相当大的问题.我们正在运行的脚本每天处理 100,000 多个通知.这可能会在每次插入之间产生大约 10,000 的间隙,因此我们可能从 100 行开始,但当我们达到 1,000 行时,最后一行的自动递增主键 ID 值超过 100000.

如果这种情况继续下去,我们将很快用完表上的自动增量值.

我们的 PostgreSQL 服务器是否配置错误?使用 Postgres 9.5.3.

我正在使用 Eloquent Schema Builder(例如 $table->increments('id'))来创建表,我不知道这是否与它有关.

推荐答案

无论插入是否成功,只要尝试插入,序列就会递增.一个简单的 update (如您的示例)不会增加它,但一个 insert on conflict update 会因为 insert 在 update 之前尝试.

一种解决方案是将id 更改为bigint.另一个是不要使用序列并自己管理它.另一个是手动插入:

with s as (
    select id
    from notifications
    where title = 'something'
), i as (
    insert into notifications (title, description)
    select 'something', 'whatever'
    where not exists (select 1 from s)
)
update notifications
set title = 'something else'
where id = (select id from s)

这假设 title 是唯一的.

本文地址:https://www.itbaoku.cn/post/1763927.html