Postgresql 序列与串行

Posted

技术标签:

【中文标题】Postgresql 序列与串行【英文标题】:Postgresql Sequence vs Serial 【发布时间】:2016-03-06 05:16:28 【问题描述】:

我想知道什么时候选择顺序更好,什么时候更好 使用串行。

我想要的是在插入后返回最后一个值

SELECT LASTVAL();

我读过这个问题 PostgreSQL Autoincrement

我以前从没用过串口。

【问题讨论】:

如果您希望将其序列号或序列分配给您刚刚插入的内容,最好使用RETURNING 语句。见***.com/questions/19167349/… A serial 在后台使用序列。基本上没有区别。在这两种情况下,在插入后立即使用 lastval() 就可以了。 【参考方案1】:

查看关于 Sequence vs. Serial 的好答案。

Sequence 只会创建唯一数字的序列。它不是数据类型。这是一个序列。例如:

create sequence testing1;
select nextval('testing1');  -- 1
select nextval('testing1');  -- 2

您可以像这样在多个地方使用相同的序列:

create sequence testing1;
create table table1(id int not null default nextval('testing1'), firstname varchar(20));
create table table2(id int not null default nextval('testing1'), firstname varchar(20));

insert into table1 (firstname) values ('tom'), ('henry');
insert into table2 (firstname) values ('tom'), ('henry');

select * from table1;

| id | firstname |
|----|-----------|
|  1 |       tom |
|  2 |     henry |

select * from table2;

| id | firstname |
|----|-----------|
|  3 |       tom |
|  4 |     henry |

串行是一种伪数据类型。它将创建一个序列对象。让我们看一个简单的表格(类似于您将在链接中看到的表格)。

create table test(field1 serial);

这将导致与表一起创建一个序列。序列名称的命名法是<tablename>_<fieldname>_seq。上面的相当于:

create sequence test_field1_seq;
create table test(field1 int not null default nextval('test_field1_seq'));

另见:http://www.postgresql.org/docs/9.3/static/datatype-numeric.html

您可以重复使用由串行数据类型自动创建的序列,或者您可以选择每个表只使用一个序列/序列。

create table table3(id serial, firstname varchar(20));
create table table4(id int not null default nextval('table3_id_seq'), firstname varchar(20));

(这里的风险是如果table3被删除了,继续使用table3的序列,会报错)

create table table5(id serial, firstname varchar(20));    
insert into table3 (firstname) values ('tom'), ('henry');
insert into table4 (firstname) values ('tom'), ('henry');
insert into table5 (firstname) values ('tom'), ('henry');

select * from table3;
| id | firstname |
|----|-----------|
|  1 |       tom |
|  2 |     henry |
        
select * from table4; -- this uses sequence created in table3
| id | firstname |
|----|-----------|
|  3 |       tom |
|  4 |     henry |
        
select * from table5;
| id | firstname |
|----|-----------|
|  1 |       tom |
|  2 |     henry |    

请随意试用示例:http://sqlfiddle.com/#!15/074ac/1

【讨论】:

是的,但serial 不是实际数据类型,它是伪数据类型 - 这是一个重要的区别:***.com/a/27309311/939860 或 ***.com/a/14651788/939860特殊情况下的序列,在这种情况下,您将使用独立序列,而不是序列列中的OWNED - 从而避免您在答案底部提到的警告。【参考方案2】:

2021 回答使用identity

我想知道什么时候选择序列比较好,什么时候选择串行比较好。

不是整个问题的答案(仅上面引用的部分),但我想它可以帮助更多的读者。你不应该使用序列或序列,你应该更喜欢identity列:

create table apps (
    id integer primary key generated always as identity
);

查看这个详细答案:https://***.com/a/55300741/978690(还有https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_serial)

【讨论】:

以上是关于Postgresql 序列与串行的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hibernate 注释映射 PostgreSQL 串行类型

为啥 PostgreSQL 会中止这个可序列化的计划

PostgreSQL:串行与身份

PostgreSQ 连接问题 FATAL: no pg_hba.conf entry for host

Postgresq9.6主从部署

PostgreSQL串行化隔离级别(SSI)的能力与实现