我在PostgreSQL中有一个表格,拥有很多列,我想要添加自增主键。
我尝试创建一个名为id
的列,类型为BIGSERIAL
,但是pgadmin报了一个错误:
ERROR: sequence must have same owner as table it is linked to.
有人知道如何解决这个问题吗?在不重新创建表的情况下,如何在PostgreSQL中添加或创建自增主键?
我在PostgreSQL中有一个表格,拥有很多列,我想要添加自增主键。
我尝试创建一个名为id
的列,类型为BIGSERIAL
,但是pgadmin报了一个错误:
ERROR: sequence must have same owner as table it is linked to.
有人知道如何解决这个问题吗?在不重新创建表的情况下,如何在PostgreSQL中添加或创建自增主键?
尝试使用此命令:
ALTER TABLE your_table ADD COLUMN key_column BIGSERIAL PRIMARY KEY;
以与您创建表的数据库用户相同的用户进行尝试。
ALTER TABLE mytable ADD PRIMARY KEY (column);
。Postgresql将检查该列不包含任何NULL值。 - A.H.bigserial
和serial
都会产生相同的错误:
ERROR: syntax error at or near "BIGSERIAL"
。 - AdilCREATE 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)
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 │
└─────────────┴──────────────────┴────────────┘
mytable_key
上,使用COPY
。
专业提示:
您应该始终在表上使用主键,因为PostgreSQL在内部使用哈希表结构来提高插入、删除、更新和查询的速度。如果有一个主键列(强制唯一且非空),它可以被依赖于为哈希函数提供一个唯一的种子。如果没有主键列可用,哈希函数会变得低效,因为它会选择其他一组列作为键。SERIAL
在幕后确实会创建一个sequence
(序列): http://www.postgresql.org/docs/9.2/static/datatype-numeric.html#DATATYPE-SERIAL - carbocation在PostgreSQL中创建一个使用自定义序列的自增主键:
第一步,创建您的序列:
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
);
第三步,将其插入到您的表中
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!'
);
第四步,观察行
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 表中为那个关键列定义一个默认值。这样更好看。
serial
是旧方式自动生成唯一值,不符合SQL
标准。
PostgreSQL 10
之后,你可以使用generated as identity
,它符合SQL
标准:
CREATE TABLE t1 (id integer primary key generated always as identity);
或者CREATE TABLE t1 (id integer primary key generated by default as identity);
by default和always之间的区别:
GENERATED ALWAYS
指示PostgreSQL
始终为标识列生成值。如果您尝试向GENERATED ALWAYS AS IDENTITY
列插入(或更新)值,则PostgreSQL
将发出错误。GENERATED BY DEFAULT
也指示PostgreSQL
为标识列生成值。但是,如果您提供了插入或更新的值,PostgreSQL
将使用该值插入到标识列中,而不是使用系统生成的值。更多信息。
如果您想在pgadmin中完成此操作,那么将会更加容易。在PostgreSQL中,要给列添加自增属性,我们首先需要创建一个自增序列并将其添加到所需的列中。我是这样做的。
1)首先,您需要确保表中有一个主键。同时,将主键的数据类型保持为bigint或smallint。(我使用了bigint,无法找到其他答案中提到的称为serial的数据类型)
2)然后,通过右键单击序列->添加新序列来添加一个序列。
如果表中没有数据,请将序列保留原样,不要进行任何更改。只需保存即可。
如果存在现有数据,请将主键列中的最后或最高值添加到“定义”选项卡中的“当前值”中,如下所示:
3)最后,在您的主键的“默认值”中添加nextval('your_sequence_name'::regclass)
代码,如下所示。
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);
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关键字会自动为相应的列创建一个序列。
ALTER SEQUENCE dummytable_id_seq RESTART WITH 1;
进行了检查,它可以正常工作。 - Asad Shakeel在PgAdmin中执行的步骤:
update myschema.mytable set a_code=cast('c'||"ref_id" as text)
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
)
IDENTITY
列而不是serial
:https://dev59.com/wGkw5IYBdhLWcg3wdKXD#9875517。 - Erwin Brandstetter