当前位置: 首页 > 知识库问答 >
问题:

每次更新时PostgreSQL自动递增

彭硕
2023-03-14

每次我执行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

这是一个相当大的问题。我们运行的脚本每天处理100000个通知。这会在每一次插入之间产生大约10000行的间隙,所以我们可能从100行开始,但当我们达到1000行时,最后一行的主键ID值会自动增加到100000以上。

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

我们的PostgreSQL服务器配置错误吗?使用Postgres 9.5.3。

我正在使用Eloquent Schema Builder(例如$table-


共有2个答案

空英达
2023-03-14

您可以通过在插入命令之前运行以下命令将自动增量列重置为最大插入值:

SELECT setval('notifications_id_seq', MAX(id)) FROM notifications;
空谦
2023-03-14
匿名用户

无论插入成功与否,只要尝试插入,序列就会增加。简单的更新(如您的示例)不会增加它,但冲突更新上的插入会增加它,因为插入是在更新之前尝试的。

一种解决方案是将 id 更改为“比金特”。另一种方法是不要使用序列并自己管理它。另一个是手动更新:

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)

这假设标题是唯一的。

 类似资料:
  • 问题内容: 作为Java学习的一部分,我使用netbeans制作了一个jForm,其中包含三个jTextField,供用户输入一些数字,然后将这些数字的总和显示在另一个jTextField中。当然,这非常简单,但是我希望能够在没有任何按钮的情况下执行此操作。我不知道每次修改3个文本字段中的任何一个时如何“更新”总和。谁能帮我? 这是我的代码(该表单是在设计模式下使用netbeans完成的): 问题

  • 具有以下数据模型: 我需要将所有价格键更新为新名称cost。在静态字段上很容易做到这一点,使用: 结果: 但是我也需要在分解数组中做这些。 在不知道细分数组中的项目数的情况下,我如何做到这一点?换句话说,我如何在jsonb数组的每个元素上应用函数。 非常感谢。

  • 我正在开发一个。能让它一变就重启吗?我正在Coffeescript中开发它。是否可以监视以便在保存更改时重新启动?

  • 问题内容: 我正在使用单个插入语句将一批记录添加到表中。我希望为每个新批次分配递增的数字,但每次都从1开始。 所以,如果我有 然后我添加两条记录(使用单个插入语句): 我如何对该表运行更新语句,以便Dave将被设置为1,而Paul将被设置为2。我不想使用游标。 问题答案: 排名功能应该可以满足您的需求。您没有提及有关如何分配序列号的任何特定规则,因此我在这里使用了名称:

  • 问题内容: 我正在尝试添加具有自动增量的主键。 我已经阅读了一些文档和其他问题-有和声明,但是不起作用。 这是我做的: 和 我怎么了 我只想将主键增加1。 问题答案: 是或多或少是一种列类型,所以说就像说,只是说: 如果您想自己创建序列,那么您想将序列中下一个值的默认值设为默认值,这意味着: 为了模拟通常的行为,您还需要使表拥有该序列: 阅读手册的“串行类型”部分可能会很有成果。 我还建议您不要对

  • 问题内容: 我有一个CI管道来构建我的android应用程序,并使用gitlab管道运行有条件的测试。我的gitlabRunner是一台ubuntu 16.04机器,在docker容器中运行每个构建。我有一个通过USB连接到gitlab运行程序的物理android设备。 最近,每次触发新的构建时,系统都会提示我允许android目标上的USB设备使用RSA指纹。问题在于指纹随着每个构建而变化。 我