如何在PostgreSQL中设置自动增量主键?

mkn*_*mkn 251 sql postgresql

我在PostgreSQL中有一个包含22列的表,我想添加一个自动增量主键.

我试图创建一个名为idBIGSERIAL类型的列,但pgadmin响应错误:

ERROR: sequence must have same owner as table it is linked to.
Run Code Online (Sandbox Code Playgroud)

有谁知道如何解决这个问题?如何在PostgreSQL中添加创建自动递增主键而无需再次重新创建表?

A.H*_*.H. 281

试试这个命令:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;
Run Code Online (Sandbox Code Playgroud)

尝试使用与创建表格的用户相同的DB用户.

  • (这里的关键是使用SERIAL或BIGSERIAL数据类型,它在幕后创建一个序列并在插入时增加/使用它) (70认同)
  • 如果要从另一个表引用它,请使用integer或bigint (15认同)
  • 还使用bigserial或serial获取语法错误.这是否有最低限度的postgresql verison? (5认同)
  • 在pgAdmin中出现此错误4."bigserial"和"serial"都给出了相同的错误:`ERROR:语法错误在"BIGSERIAL"或附近 (3认同)
  • @satishkilari:是的,语法为`ALTER TABLE mytable ADD PRIMARY KEY(column);`。Postgresql将检查该列是否不包含NULL。 (2认同)
  • @PirateApp:您的问题的典型答案是:并发事务中不能使用无间隙计数器。您将迫使数据库将对表的写入序列化,这会严重影响性能。因此,大多数DB(和Postgres)默认使用非无间隙计数器。 (2认同)

Eri*_*ski 248

在postgresql中自动递增主键:

第1步,创建表:

CREATE TABLE epictable
(
    mytable_key    serial primary key,
    moobars        VARCHAR(40) not null,
    foobars        DATE
);
Run Code Online (Sandbox Code Playgroud)

第2步,像这样在表中插入值,注意在第一个参数列表中没有指定mytable_key,这会导致默认序列自动增量.

insert into epictable(moobars,foobars) values('delicious moobars','2012-05-01')
insert into epictable(moobars,foobars) values('worldwide interblag','2012-05-02')
Run Code Online (Sandbox Code Playgroud)

第3步,从你的表中选择*:

el@voyager$ psql -U pgadmin -d kurz_prod -c "select * from epictable"
Run Code Online (Sandbox Code Playgroud)

第4步,解释输出:

mytable_key  |        moobars        |  foobars   
-------------+-----------------------+------------
           1 | delicious moobars     | 2012-05-01
           2 | world wide interblags | 2012-05-02
(2 rows)
Run Code Online (Sandbox Code Playgroud)

观察mytable_key列已自动递增.

专家提示:

您应该始终在表上使用主键,因为postgresql在内部使用哈希表结构来提高插入,删除,更新和选择的速度.如果主键列(强制唯一且非空)可用,则可以依赖于为散列函数提供唯一种子.如果没有主键列可用,则散列函数变得效率低,因为它选择一些其他列作为键.

  • 一个小的挑剔,`SERIAL`确实在幕后创建了一个`序列':http://www.postgresql.org/docs/9.2/static/datatype-numeric.html#DATATYPE-SERIAL (21认同)

Ism*_*ail 34

serial是自动生成唯一值的旧方法,它不是SQL标准的一部分。

之后PostgreSQL 10,您可以使用generated as identity,它符合SQL标准:

CREATE TABLE t1 (id integer primary key generated always as identity);
Run Code Online (Sandbox Code Playgroud)

或者

CREATE TABLE t1 (id integer primary key generated by default as identity); 
Run Code Online (Sandbox Code Playgroud)

默认和始终的区别:

  • 指示始终为标识列生成一个值GENERATED ALWAYSPostgreSQL如果您尝试将值插入(或更新)到GENERATED ALWAYS AS IDENTITY列中,PostgreSQL将发出错误。
  • 它还GENERATED BY DEFAULT指示PostgreSQL为标识列生成一个值。但是,如果您提供用于插入或更新的值,PostgreSQL则将使用该值插入到标识列中,而不是使用系统生成的值。

了解更多信息


Eri*_*ski 33

使用自定义序列在postgresql中创建自动递增主键:

第1步,创建序列:

create sequence splog_adfarm_seq
    start 1
    increment 1
    NO MAXVALUE
    CACHE 1;
ALTER TABLE fact_stock_data_detail_seq
OWNER TO pgadmin;
Run Code Online (Sandbox Code Playgroud)

第2步,创建你的表

CREATE TABLE splog_adfarm
(
    splog_key    INT unique not null,
    splog_value  VARCHAR(100) not null
);
Run Code Online (Sandbox Code Playgroud)

第3步,插入你的表格

insert into splog_adfarm values (
    nextval('splog_adfarm_seq'), 
    'Is your family tree a directed acyclic graph?'
);

insert into splog_adfarm values (
    nextval('splog_adfarm_seq'), 
    'Will the smart cookies catch the crumb?  Find out now!'
);
Run Code Online (Sandbox Code Playgroud)

第4步,观察行

el@defiant ~ $ psql -U pgadmin -d kurz_prod -c "select * from splog_adfarm"

splog_key |                            splog_value                             
----------+--------------------------------------------------------------------
        1 | Is your family tree a directed acyclic graph?
        2 | Will the smart cookies catch the crumb?  Find out now!
(3 rows)
Run Code Online (Sandbox Code Playgroud)

这两行具有从1开始的键,并按序列的定义递增1.

Bonus Elite ProTip:

程序员讨厌打字,打字nextval('splog_adfarm_seq')就很烦人.您可以输入DEFAULT该参数,如下所示:

insert into splog_adfarm values (
    DEFAULT, 
    'Sufficient intelligence to outwit a thimble.'
);
Run Code Online (Sandbox Code Playgroud)

要使上述工作正常,您必须在splog_adfarm表上为该键列定义默认值.哪个更漂亮.

  • 自定义序列有什么好处?安全性可能吗? (2认同)
  • @Masi 自定义序列的一种用途可能是使主-主复制更容易-如果两个数据中心之间的数据链接中断,这将很有用-允许在具有不同 ID 的两台服务器上创建记录,从而然后可以轻松地同步数据库备份,同时保留在不同位置生成的 ID。 (2认同)

toi*_*ing 16

如果你想在pgadmin中这样做,那就容易多了.在postgressql中,为了向列添加自动增量,我们首先需要创建一个自动增量序列并将其添加到所需的列.我确实喜欢这个.

1)首先,您需要确保您的表有一个主键.还要将主键的数据类型保留为bigint或smallint.(我使用bigint,找不到一个名为serial的数据类型,如其他答案中提到的那样)

2)然后通过右键单击sequence-> 添加新序列添加序列.如果表中没有数据,请按原样保留序列,不要进行任何更改.只需保存它.如果存在现有数据,请将主键列中的最后一个或最高值添加到"定义"选项卡中的"当前"值,如下所示. 在此输入图像描述

3)最后,将该行添加nextval('your_sequence_name'::regclass)到主键中的Default值,如下所示.

在此输入图像描述 确保序列名称在此处正确.这就是全部,自动增量应该有效.


aca*_*uci 5

如果要在序列中使用数字,请使用以下内容定义新的序列

CREATE SEQUENCE public.your_sequence
    INCREMENT 1
    START 1
    MINVALUE 1
;
Run Code Online (Sandbox Code Playgroud)

然后更改表以使用ID的顺序:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
Run Code Online (Sandbox Code Playgroud)