首页 > 解决方案 > 如果在使用自动增量时主键存在时插入新行会怎样?

问题描述

我正在使用 PGsql 并将一些数据从另一个数据库传输到我的新数据库中。该表的记录从 PK 200 开始。表的主键(bigint - autoincrementing)当前从 0 开始。如果我继续插入记录,最终它将达到 200。我的问题是,这些记录在尝试插入记录 200?还是 PGsql 会知道冲突,然后找到下一个可用的 AI 索引(比如 234)?谢谢!如果会导致冲突,如何将我的表的当前索引设置为数据的最后一个索引?(如 234)。

标签: sqlpostgresqlsql-insertauto-incrementbigint

解决方案


我的问题是,这些记录在尝试插入记录 200 时会产生问题吗?

假设您有一个serial专栏或类似的东西:是的,这将产生一个问题。序列号不知道某些序列不可用,sp 这将导致重复键错误。同时,序列也会因此类错误而增加,下一次调用将返回下一个数字,依此类推。

这很容易重现:

create table t (id serial primary key, val text);

insert into t (id, val) values (2, 'blocker');
-- 1 rows affected

insert into t (val) values ('foo');
-- 1 rows affected

insert into t (val) values ('bar');
-- ERROR:  duplicate key value violates unique constraint "t_pkey"
-- DETAIL:  Key (id)=(2) already exists.

insert into t (val) values ('baz');
-- 1 rows affected

select * from t order by id;

id | val    
-: | :------
 1 | foo    
 2 | blocker
 3 | baz    

一种解决方案是重置序列:唯一安全的起点是表的高水位线:

select setval(
    't_id_seq', 
    coalesce((select max(id) + 1 from t), 1), 
    false
);

DB Fiddlde 上的演示:您可以取消注释该setval()语句以查看它如何避免错误。


推荐阅读