PostgreSQL中如何设置自增主键?

发布于 2024-12-09 06:17:07 字数 257 浏览 1 评论 0原文

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

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

错误:序列必须与其链接到的表具有相同的所有者。

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

I have a table in PostgreSQL with many columns, and I want to add an auto increment primary key.

I tried to create a column called id of type BIGSERIAL but pgadmin responded with an error:

ERROR: sequence must have same owner as table it is linked to.

Does anyone know how to fix this issue? How do I add or create an auto-incrementing primary key in PostgreSQL without recreating the table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

樱花细雨 2024-12-16 06:17:07

尝试此命令:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

使用与您创建表相同的数据库用户进行尝试。

Try this command:

ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

Try it with the same DB-user as the one you have created the table.

唔猫 2024-12-16 06:17:07

postgresql 中自动递增主键:

创建表:

CREATE TABLE epictable
(
    mytable_key    serial primary key,
    moobars        VARCHAR(40) not null,
    foobars        DATE
);

将值插入表中:

insert into epictable(moobars,foobars) values('delicious moobar','2012-05-01');
insert into epictable(moobars,foobars) values('WorldWideBlag','2012-05-02');

从表中选择 *:

select * from epictable

mytable_key  |        moobars        |  foobars   
-------------+-----------------------+------------
           1 | delicious moobar      | 2012-05-01
           2 | WorldWideBlag         | 2012-05-02
(2 rows)

观察 mytable_key 列已被自动递增。

Postgresql COPY 不观察序列

自动递增序列键不会像 COPY 命令那样通过从文件批量导入数据来断言自身。你会得到一个
psql:错误:重复的键值违反了唯一约束。解决此问题的一种方法是将其复制到新表中,然后使用插入:

COPY epictable TO '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

CREATE TABLE epictable2 ( mytable_key    integer, 
                          moobars        VARCHAR(40) not null, 
                          foobars        DATE ); 

COPY epictable2(mytable_key, moobars, foobars) FROM 
    '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

--and again to make the duplicates requiring an autoincrement:
COPY epictable2(mytable_key, moobars, foobars) FROM 
    '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

insert into epictable(moobars, foobars) (
    select moobars, foobars from epictable2
);

select * from epictable;

┌─────────────┬──────────────────┬────────────┐
│ mytable_key │     moobars      │  foobars   │
├─────────────┼──────────────────┼────────────┤
│           1 │ delicious moobar │ 2012-05-01 │
│           2 │ WorldWideBlag    │ 2012-05-02 │
│           3 │ delicious moobar │ 2012-05-01 │
│           4 │ WorldWideBlag    │ 2012-05-02 │
│           5 │ delicious moobar │ 2012-05-01 │
│           6 │ WorldWideBlag    │ 2012-05-02 │
└─────────────┴──────────────────┴────────────┘

使用 COPY 观察 mytable_key 上发生自动递增。

专业提示

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

如果您想更多地控制序列键的行为,请参阅 postgresql 序列。

Auto incrementing primary key in postgresql:

Create your table:

CREATE TABLE epictable
(
    mytable_key    serial primary key,
    moobars        VARCHAR(40) not null,
    foobars        DATE
);

Insert values into your table:

insert into epictable(moobars,foobars) values('delicious moobar','2012-05-01');
insert into epictable(moobars,foobars) values('WorldWideBlag','2012-05-02');

select * from your table:

select * from epictable

mytable_key  |        moobars        |  foobars   
-------------+-----------------------+------------
           1 | delicious moobar      | 2012-05-01
           2 | WorldWideBlag         | 2012-05-02
(2 rows)

Observe that mytable_key column has been auto incremented.

Postgresql COPY doesn't observe serials

An auto incrementing serial key doesn't assert itself with bulk imports of data from file, like COPY command does. You'll get a
psql:ERROR: duplicate key value violates unique constraint. One way to fix that is copy it into a new table then use insert thustly:

COPY epictable TO '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

CREATE TABLE epictable2 ( mytable_key    integer, 
                          moobars        VARCHAR(40) not null, 
                          foobars        DATE ); 

COPY epictable2(mytable_key, moobars, foobars) FROM 
    '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

--and again to make the duplicates requiring an autoincrement:
COPY epictable2(mytable_key, moobars, foobars) FROM 
    '/tmp/etbackup.csv' DELIMITER ',' CSV HEADER;

insert into epictable(moobars, foobars) (
    select moobars, foobars from epictable2
);

select * from epictable;

┌─────────────┬──────────────────┬────────────┐
│ mytable_key │     moobars      │  foobars   │
├─────────────┼──────────────────┼────────────┤
│           1 │ delicious moobar │ 2012-05-01 │
│           2 │ WorldWideBlag    │ 2012-05-02 │
│           3 │ delicious moobar │ 2012-05-01 │
│           4 │ WorldWideBlag    │ 2012-05-02 │
│           5 │ delicious moobar │ 2012-05-01 │
│           6 │ WorldWideBlag    │ 2012-05-02 │
└─────────────┴──────────────────┴────────────┘

Observe Auto-incrementing happens on mytable_key with COPY.

ProTips:

You should always be using a primary key on your table because postgresql internally uses hash table structures to increase the speed of inserts, deletes, updates and selects. If a primary key column (which is forced unique and non-null) is available, it can be depended on to provide a unique seed for the hash function. If no primary key column is available, the hash function becomes inefficient as it selects some other set of columns as a key.

If you want more control over the behavior of the serial key, then see postgresql sequences.

倦话 2024-12-16 06:17:07

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

PostgreSQL 10之后,您可以使用生成的身份,它符合SQL标准:

CREATE TABLE t1 (id integer primary key generated always as identity);

或者

CREATE TABLE t1 (id integer primary key generated by default as identity); 

默认和始终之间的区别:

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

了解更多信息

serial is the old way to auto generate unique values and it is not part of the SQL standard.

After PostgreSQL 10, you can use generated as identity, it is compliant with SQL standard:

CREATE TABLE t1 (id integer primary key generated always as identity);

or

CREATE TABLE t1 (id integer primary key generated by default as identity); 

The difference between by default and always:

  • The GENERATED ALWAYS instructs PostgreSQL to always generate a value for the identity column. If you attempt to insert (or update) values into the GENERATED ALWAYS AS IDENTITY column, PostgreSQL will issue an error.
  • The GENERATED BY DEFAULT also instructs PostgreSQL to generate a value for the identity column. However, if you supply a value for insert or update, PostgreSQL will use that value to insert into the identity column instead of using the system-generated value.

For more information.

梦幻的味道 2024-12-16 06:17:07

使用自定义序列在 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;

第 2 步,创建表

CREATE TABLE splog_adfarm
(
    splog_key    INT unique not null,
    splog_value  VARCHAR(100) not null
);

第 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!'
);

第 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)

这两行的键从 1 开始,按序列定义以 1 递增。

奖励精英专业提示:

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

insert into splog_adfarm values (
    DEFAULT, 
    'Sufficient intelligence to outwit a thimble.'
);

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

Create an auto incrementing primary key in postgresql, using a custom sequence:

Step 1, create your sequence:

create sequence splog_adfarm_seq
    start 1
    increment 1
    NO MAXVALUE
    CACHE 1;
ALTER TABLE fact_stock_data_detail_seq
OWNER TO pgadmin;

Step 2, create your table

CREATE TABLE splog_adfarm
(
    splog_key    INT unique not null,
    splog_value  VARCHAR(100) not null
);

Step 3, insert into your table

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!'
);

Step 4, observe the rows

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)

The two rows have keys that start at 1 and are incremented by 1, as defined by the sequence.

Bonus Elite ProTip:

Programmers hate typing, and typing out the nextval('splog_adfarm_seq') is annoying. You can type DEFAULT for that parameter instead, like this:

insert into splog_adfarm values (
    DEFAULT, 
    'Sufficient intelligence to outwit a thimble.'
);

For the above to work, you have to define a default value for that key column on splog_adfarm table. Which is prettier.

淡写薰衣草的香 2024-12-16 06:17:07

如果你想在 pgadmin 中执行此操作,那就容易得多。在postgressql中,要为列添加自动增量,我们首先需要创建一个自动增量序列并将其添加到所需的列中。我确实喜欢这个。

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

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

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

输入图像描述这里
确保此处的序列名称正确。这就是全部,自动增量应该可以工作。

If you want to do this in pgadmin, it is much easier. It seems in postgressql, to add a auto increment to a column, we first need to create a auto increment sequence and add it to the required column. I did like this.

1) Firstly you need to make sure there is a primary key for your table. Also keep the data type of the primary key in bigint or smallint. (I used bigint, could not find a datatype called serial as mentioned in other answers elsewhere)

2)Then add a sequence by right clicking on sequence-> add new sequence.
If there is no data in the table, leave the sequence as it is, don't make any changes. Just save it.
If there is existing data, add the last or highest value in the primary key column to the Current value in Definitions tab as shown below.
enter image description here

3)Finally, add the line nextval('your_sequence_name'::regclass) to the Default value in your primary key as shown below.

enter image description here
Make sure the sequence name is correct here. This is all and auto increment should work.

千仐 2024-12-16 06:17:07

如果要在序列中使用数字,请使用类似的内容定义一个新序列

CREATE SEQUENCE public.your_sequence
    INCREMENT 1
    START 1
    MINVALUE 1
;

,然后更改表以使用该序列作为 id:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);

If you want to use numbers in a sequence, define a new sequence with something like

CREATE SEQUENCE public.your_sequence
    INCREMENT 1
    START 1
    MINVALUE 1
;

and then alter the table to use the sequence for the id:

ALTER TABLE ONLY table ALTER COLUMN id SET DEFAULT nextval('your_sequence'::regclass);
你是我的挚爱i 2024-12-16 06:17:07

我尝试了以下脚本来成功自动增加 P​​ostgreSQL 中的主键。

CREATE SEQUENCE dummy_id_seq
    START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

CREATE table dummyTable (
    id bigint DEFAULT nextval('dummy_id_seq'::regclass) NOT NULL,
    name character varying(50)
);

编辑:

CREATE table dummyTable (
    id SERIAL NOT NULL,
    name character varying(50)
)

SERIAL 关键字会自动为相应列创建序列。

I have tried the following script to successfully auto-increment the primary key in PostgreSQL.

CREATE SEQUENCE dummy_id_seq
    START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

CREATE table dummyTable (
    id bigint DEFAULT nextval('dummy_id_seq'::regclass) NOT NULL,
    name character varying(50)
);

EDIT:

CREATE table dummyTable (
    id SERIAL NOT NULL,
    name character varying(50)
)

SERIAL keyword automatically create a sequence for respective column.

残疾 2024-12-16 06:17:07

在 PgAdmin 上执行此操作的步骤:

  • CREATE SEQUENCE sequnence_title START 1; // 如果表存在最后一个 id
  • 将此序列添加到主键,表 - 属性 - 列 - column_id(主键) 编辑 - 约束 - 添加 nextval('sequnence_title'::regclass) 到
    字段默认值。

Steps to do it on PgAdmin:

  • CREATE SEQUENCE sequnence_title START 1; // if table exist last id
  • Add this sequense to the primary key, table - properties - columns - column_id(primary key) edit - Constraints - Add nextval('sequnence_title'::regclass) to
    the field default.
花辞树 2024-12-16 06:17:07

也许我回答这个问题有点晚了,但我正在工作中研究这个主题:)

我想写专栏 'a_code' = c1,c2,c3,c4...

首先我打开了一个专栏名称为 ref_id ,类型为 serial
然后我用这个命令解决了我的问题:

update myschema.mytable set a_code=cast('c'||"ref_id" as text) 

Maybe I'm a bit of late to answer this question, but I'm working on this subject at my job :)

I wanted to write column 'a_code' = c1,c2,c3,c4...

Firstly I opened a column with the name ref_id and the type serial.
Then I solved my problem with this command:

update myschema.mytable set a_code=cast('c'||"ref_id" as text) 
徒留西风 2024-12-16 06:17:07

您可以使用以下代码进行自动增量

Create table public.EmployeeDapper
(
    Id int not null generated by default as identity(increment by 1 start 1 
    minvalue 1 maxvalue 2147483647 cache 1),

    Name varchar(50) not null,
    Age int not null,
    Position varchar(50)not null
)

You can use below code for auto increment

Create table public.EmployeeDapper
(
    Id int not null generated by default as identity(increment by 1 start 1 
    minvalue 1 maxvalue 2147483647 cache 1),

    Name varchar(50) not null,
    Age int not null,
    Position varchar(50)not null
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文