【问题标题】:What happens if a new row is inserted when the primary key exists when using auto increment?如果在使用自动增量时主键存在时插入新行会怎样?
【发布时间】:2021-03-31 17:40:35
【问题描述】:

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

【问题讨论】:

    标签: sql postgresql sql-insert auto-increment bigint


    【解决方案1】:

    我的问题是,在尝试插入记录 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() 语句,看看它是如何避免错误的。

    【讨论】:

    • 不确定这是什么意思,但默认值是这样的:nextval('line_inventory_logsheet_head_logsheet_id_seq'::regclass)
    猜你喜欢
    • 2012-06-20
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多