You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL Upsert更新记录时为何递增序列last_value?

关于PostgreSQL Upsert导致bigserial序列断层的疑问

我有一个PostgreSQL表,主键id为bigserial类型,目前序列值已达数百万,但表中实际仅有数百条记录。该表频繁执行以下Upsert语句:

INSERT INTO test_table (ticker,column1) VALUES ('a','1') ON CONFLICT (ticker) DO UPDATE SET column1=EXCLUDED.column1;

测试后发现:当ticker已存在(触发更新操作)时,序列仍会递增;只有插入新记录时,Upsert才会将序列last_value+1作为id值。

为验证该行为,我创建了测试表:

CREATE TABLE public.test_table (
    id bigserial NOT NULL,
    ticker varchar(10) NOT NULL,
    column1 varchar(10) NULL,
    CONSTRAINT test_table_pk PRIMARY KEY (id),
    CONSTRAINT test_table_unique UNIQUE (ticker) 
);

自动生成的序列test_table_id_seq初始last_value为1。执行首次Upsert插入新记录后,last_value仍为1,id为1,符合预期。

随后执行3次触发更新操作的Upsert语句后,序列last_value增至4,但表中最高id仍为1。再插入新记录时id变为5,出现了序列断层。

目前我只能通过每次Upsert后执行以下语句重置序列来避免断层:

SELECT setval('test_table_id_seq', (SELECT MAX(id) FROM test_table));

请问该行为是否正常?我是否遗漏了什么关键点?

内容的提问来源于stack exchange,提问作者jr-scalawag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:52:08