使用自动增量时,当主键存在时插入新行会发生什么?

问题描述

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

解决方法

我的问题是,这些记录在尝试插入记录 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
);

Demo on DB Fiddlde:您可以取消注释 setval() 语句以查看它如何避免错误。