[[toc]]
适用范围
PostgreSQL 12.8+
序列概述
- 序列是bigint 整数,取值范围:-263~263-1
- 序列属于relation其中之一,所以因同一schema下,不能与ordinary table, index, TOAST table,view,materialized view, composite type, foreign table, partitioned table, partitioned index同名。
- 序列创建后,可以使用函数currval(),nextval(),setval(),lastval()对其进行操作。
| 函数 | 返回值 | 说明 |
|---|---|---|
| currval() | bigint | nextval返回当前会话中此序列最近获得的值。(如果nextval在此会话中从未为此序列调用过,则会报告错误。)因为这将返回一个会话本地值,所以它给出了一个可预测的答案,无论nextval自当前会话以来其他会话是否已执行。此功能需要USAGE或SELECT对序列具有特权。 |
| nextval() | bigint | 将序列对象前进到下一个值并返回该值。这是原子完成的:即使多个会话nextval同时执行,每个会话都将安全地接收不同的序列值。如果使用默认参数创建了序列对象,则连续nextval调用将返回从 1 开始的连续值。此功能需要USAGE或UPDATE对序列具有特权。 |
| setval() | bigint | 设置序列对象的当前值,以及可选的is_called标志。双参数形式将序列的last_value字段设置为指定值并将其is_called字段设置为true,这意味着下一个nextval将在返回值之前推进序列。将报告的currval值也设置为指定值。在三参数形式中,is_called可以设置为true或false。true与双参数形式的效果相同。如果设置为false,则 nextval将准确返回指定的值,并且序列推进从以下 开始nextval。此功能需要UPDATE序列的特权。 |
| lastval() | bigint | nextval返回当前会话中最近返回的值。此函数与 相同currval,不同之处在于它不是将序列名称作为参数,而是引用nextval当前会话中最近应用的序列。lastval如果nextval当前会话中尚未调用,则调用是错误的。此功能需要USAGE或SELECT对最后使用的序列具有特权。 |
序列操作
- 创建一个索引
postgres@[local]:1931=#26535 create schema seq;
CREATE SCHEMA
postgres@[local]:1931=#26535 create sequence seq.seq1 minvalue 1 maxvalue 100 start 1;
CREATE SEQUENCE
postgres@[local]:1931=#26535 select * from seq.seq1
postgres-# ;
last_value | log_cnt | is_called
------------+---------+-----------
1 | 0 | f
(1 row)
- 表中使用序列
create table seq.product(id int default nextval('seq.seq1'),
name varchar);
postgres@[local]:1931=#26535 insert into seq.product values(10,'tom');
INSERT 0 1
postgres@[local]:1931=#26535 insert into seq.product (name)values('tom');
INSERT 0 1
postgres@[local]:1931=#26535 insert into seq.product (name)values('tom');
INSERT 0 1
postgres@[local]:1931=#26535 select * from seq.product;
id | name
----+------
10 | tom
1 | tom
2 | tom
(3 rows)
- 修改序列属性
#修改前
postgres@[local]:1931=#26535 select * from pg_sequences where sequencename='seq1';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+--------------+---------------+-----------+-------------+-----------+-----------+--------------+-------+------------+------------
seq | seq1 | postgres | bigint | 1 | 1 | 100 | 1 | f | 1 | 2
(1 row)
#修改后
postgres@[local]:1931=#26535 alter sequence seq.seq1 maxvalue 1000 start with 20 cache 5 restart 5;
ALTER SEQUENCE
postgres@[local]:1931=#26535 select * from pg_sequences where sequencename='seq1';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+--------------+---------------+-----------+-------------+-----------+-----------+--------------+-------+------------+------------
seq | seq1 | postgres | bigint | 20 | 1 | 1000 | 1 | f | 5 |
(1 row)
- 查看序列 select * from seq_name 或 select currval()
postgres@[local]:1931=#26535 create sequence seq.seq2 start with 1 maxvalue 9999 increment by 1;
CREATE SEQUENCE
postgres@[local]:1931=#26535 select * from seq.seq2;
last_value | log_cnt | is_called
------------+---------+-----------
1 | 0 | f
(1 row)
#这里要非常注意currval()函数,只有在当前会话,调用过nextval()后,才会返回最近的值,不然会报错。
postgres@[local]:1931=#26535 select currval('seq.seq2');
ERROR: currval of sequence "seq2" is not yet defined in this session
postgres@[local]:1931=#26535 select nextval('seq.seq2');
nextval
---------
1
(1 row)
postgres@[local]:1931=#26535 select currval('seq.seq2');
currval
---------
1
(1 row)
- 查看最近的值 lastval() 与currval()相似,必须先运行nextval()
#如不先运行nextval(),则报以下错。
[postgres@pg14 ~]$ psql
psql (14.2)
Type "help" for help.
postgres@[local]:1931=#26774 select lastval();
ERROR: lastval is not yet defined in this session
postgres@[local]:1931=#26774
postgres@[local]:1931=#26774 select nextval('seq.seq2');
nextval
---------
3
(1 row)
postgres@[local]:1931=#26774 select lastval();
lastval
---------
3
(1 row)
- reset序列 setval()
# 不写boolean 与 boolean=true 等同,运行nextval()时,加setval + 1
postgres@[local]:1931=#26774 select setval('seq.seq2',1);
setval
--------
1
(1 row)
postgres@[local]:1931=#26774 select nextval('seq.seq2');
nextval
---------
2
(1 row)
postgres@[local]:1931=#26774 select setval('seq.seq2',1,true);
setval
--------
1
(1 row)
postgres@[local]:1931=#26774 select nextval('seq.seq2');
nextval
---------
2
(1 row)
# 当boolean = false 运行nextval()时,返回setval值
postgres@[local]:1931=#26774 select setval('seq.seq2',1,false);
setval
--------
1
(1 row)
postgres@[local]:1931=#26774 select nextval('seq.seq2');
nextval
---------
1
(1 row)
- 删除序列
postgres@[local]:1931=#26774 drop sequence seq.seq2;
DROP SEQUENCE
postgres@[local]:1931=#26774
- 删除正在被表使用的序列会报错,只有将表删除后,才能删序列
postgres@[local]:1931=#26774 drop sequence seq.seq1;
ERROR: cannot drop sequence seq.seq1 because other objects depend on it
DETAIL: default value for column id of table seq.product depends on sequence seq.seq1
HINT: Use DROP ... CASCADE to drop the dependent objects too.
postgres@[local]:1931=#26774 drop table seq.product;
DROP TABLE
postgres@[local]:1931=#26774 drop sequence seq.seq1;
DROP SEQUENCE
- 那么列为自增类型时,是序列吗
postgres@[local]:1931=#26774 create table seq.tab_seq(id serial,name text);
CREATE TABLE
postgres@[local]:1931=#26774 \d seq.tab_seq
Table "seq.tab_seq"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+-----------------------------------------
id | integer | | not null | nextval('seq.tab_seq_id_seq'::regclass)
name | text | | |
postgres@[local]:1931=#26774 select * from pg_sequences where sequencename='tab_seq_id_seq';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+----------------+---------------+-----------+-------------+-----------+------------+--------------+-------+------------+------------
seq | tab_seq_id_seq | postgres | integer | 1 | 1 | 2147483647 | 1 | f | 1 |
(1 row)
# 可以看自动创建一个seq.tab_seq_id_seq序列,取值范围为1~2^31-1
# 如果删除自增列,tab_seq_id_seq会怎么样呢?
postgres@[local]:1931=#26774 alter table seq.tab_seq drop column id;
ALTER TABLE
postgres@[local]:1931=#26774 \d seq.tab_seq
Table "seq.tab_seq"
Column | Type | Collation | Nullable | Default
--------+------+-----------+----------+---------
name | text | | |
postgres@[local]:1931=#26774 select * from pg_sequences where sequencename='tab_seq_id_seq';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+--------------+---------------+-----------+-------------+-----------+-----------+--------------+-------+------------+------------
(0 rows)
# 可以删除列同时,序列自动删除,这是与手动创建序列不同点
# 同样猜测删除表同时,序列也会自动删除
postgres@[local]:1931=#26774 alter table seq.tab_seq add column id serial;
ALTER TABLE
postgres@[local]:1931=#26774 select * from pg_sequences where sequencename='tab_seq_id_seq';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+----------------+---------------+-----------+-------------+-----------+------------+--------------+-------+------------+------------
seq | tab_seq_id_seq | postgres | integer | 1 | 1 | 2147483647 | 1 | f | 1 |
(1 row)
postgres@[local]:1931=#26774 drop table seq.tab_seq;
DROP TABLE
postgres@[local]:1931=#26774 select * from pg_sequences where sequencename='tab_seq_id_seq';
schemaname | sequencename | sequenceowner | data_type | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value
------------+--------------+---------------+-----------+-------------+-----------+-----------+--------------+-------+------------+------------
(0 rows)
参考文档
https://www.postgresql.org/docs/current/functions-sequence.html
https://www.postgresql.org/docs/current/sql-altertable.html
https://www.postgresql.org/docs/current/sql-createsequence.html
https://www.postgresql.org/search/?q=alter+sequence
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




