主键序列不存在

primary key sequence does not exist

我有一个 postgresql 数据库,在迁移到较新版本并导入我的旧数据后,我的主键出现问题:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint   
"browser_link_pkey"  Detail: Key (id)=(173) already exists.

所以我想重置我的序列,但是 运行:

select nextval('browser_link_id_seq')

也失败了:

column „browser_link_id_seq“ does not exist
SQL Status:42703

这是 SQL 用于 table 创建

CREATE TABLE browser_link (
    id bigint NOT NULL,
....
);
ALTER TABLE ONLY browser_link
ADD CONSTRAINT browser_link_pkey PRIMARY KEY (id);

我尝试选择序列号,但似乎 none 存在:

postgres=# \connect historify
You are now connected to database "historify" as user "postgres".
historify=# select pg_get_serial_sequence('browser_link', 'id');
 pg_get_serial_sequence
------------------------

(1 row)

我正在使用 postgresql 9.5.3。此外,在错误发生之前,id 列确实按预期递增,所以它确实有效。

现在我的两个问题:

  1. 为什么自动增量有效?
  2. 如何重置自动增量计数器?

Postgres 中的序列号是整数,默认值 由序列 提供。 在下面的片段中,table "one" 和 table "two" 完全等价:

CREATE TABLE one
( id bigserial NOT NULL PRIMARY KEY
  , name varchar
);

CREATE TABLE two
( id bigint NOT NULL PRIMARY KEY
  , name varchar
);
CREATE SEQUENCE "two_id_seq"
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;

ALTER SEQUENCE "two_id_seq"
        OWNED BY two.id
        ;
ALTER TABLE two
        ALTER COLUMN id SET default nextval('two_id_seq')
        ;

\d one
\d two

如您所见,one table 的 serial 语法更加紧凑(它实际上是所需 4 个语句的 shorthand 符号对于 two table)

因此,在您的问题table 中,您可以使用 bigserial 而不是 bigint 作为数据类型重建 table,或者 "attach"通过 ALTER table ... ALTER COLUMN ... 语法将现有序列号添加到现有 id 列。


您可以通过 'setval('name', val); 将序列设置为新值,例如:

INSERT INTO two(id, name) VALUES ( 13, 'thirteen' );
select nextval('two_id_seq');
SELECT setval ('two_id_seq', (select max(id) FROM two));
select * from two;
select nextval('two_id_seq');

结果:

INSERT 0 1
 nextval 
---------
       1
(1 row)

 setval 
--------
     13
(1 row)

 id |   name   
----+----------
 13 | thirteen
(1 row)

 nextval 
---------
      14
(1 row)