postgres的序列(Sequence)的使用
介绍
序列对象(也叫序列生成器)就是用CREATE SEQUENCE 创建的特殊的单行表。一个序列对象通常用于为行或者表生成唯一的标识符。
二、创建序列
方法一:直接在表中指定字段类型为serial 类型
david=# create table tbl_xulie (
david(# id serial,
david(# name text);
NOTICE: CREATE TABLE will create implicit sequence "tbl_xulie_id_seq" for serial column "tbl_xulie.id"
CREATE TABLE
david=#
方法二:先创建序列名称,然后在新建的表中列属性指定序列就可以了,该列需int 类型
创建序列的语法:
CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table.column | NONE } ]
实例 :
1、查询数据库中有哪些序列
--查看数据库中有哪些序列
--r =普通表, i =索引,S =序列,v =视图,m =物化视图, c =复合类型,t = TOAST表,f =外部表
select * from pg_class where relkind='S'
2、查找Sequence中的值
SELECT nextval(‘seq_commodity’);
这里nextval表示下一个值
3、查看表中的 序列
david=# \d tbl_xulieTable "public.tbl_xulie"Column | Type | Modifiers
--------+---------+--------------------------------------------------------id | integer | not null default nextval('tbl_xulie_id_seq'::regclass)name | text | david=# \d tbl_xulie2Table "public.tbl_xulie2"Column | Type | Modifiers
--------+---------+---------------------------------------------------------id | integer | not null default nextval('tbl_xulie2_id_seq'::regclass)name | text |
4、查看序列属性
david=# \d tbl_xulie_id_seqSequence "public.tbl_xulie_id_seq"Column | Type | Value
---------------+---------+---------------------sequence_name | name | tbl_xulie_id_seqlast_value | bigint | 1start_value | bigint | 1increment_by | bigint | 1max_value | bigint | 9223372036854775807min_value | bigint | 1cache_value | bigint | 1log_cnt | bigint | 0is_cycled | boolean | fis_called | boolean | f
Owned by: public.tbl_xulie.id
查看序列
david=# select * from tbl_xulie2_id_seq;
序列应用
1、在INSERT 命令中使用序列
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'David');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sandy');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+-------
| David
| Sandy
(2 rows)
1.2 数据迁移后更新序列
david=# truncate tbl_xulie;
TRUNCATE TABLE
david=#
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sandy');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'David');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Eagle');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Miles');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Simon');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Rock');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Peter');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sally');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Nicole');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Monica');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Renee');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+--------
| Sandy
| David
| Eagle
| Miles
| Simon
| Rock
| Peter
| Sally
| Nicole
| Monica
| Renee
(11 rows)david=# copy tbl_xulie to '/tmp/tbl_xulie.sql';
COPY 11
david=# truncate tbl_xulie;
TRUNCATE TABLE
david=# alter sequence tbl_xulie_id_seq restart with 100;
ALTER SEQUENCE
david=# select currval('tbl_xulie_id_seq');currval
---------
(1 row)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)david=# begin;
BEGIN
david=# copy tbl_xulie from '/tmp/tbl_xulie.sql';
COPY 11
david=# select setval('tbl_xulie_id_seq', max(id)) from tbl_xulie;setval
--------
(1 row)david=# end;
COMMIT
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Flash');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+--------
| Sandy
| David
| Eagle
| Miles
| Simon
| Rock
| Peter
| Sally
| Nicole
| Monica
| Renee
| Flash
(12 rows)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)
序列函数
下面序列函数,为我们从序列对象中获取最新的序列值提供了简单和并发读取安全的方法。
1、1查看下一个序列值
david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)
1.2 查看序列最近使用值
david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)david=# select currval('tbl_xulie_id_seq');currval
---------
(1 row)david=# select currval('tbl_xulie_id_seq');currval
---------
(1 row)
重置序列
1、1方法一:使用序列函数
a. setval(regclass, bigint)
david=# truncate tbl_xulie;
TRUNCATE TABLE
david=# select setval('tbl_xulie_id_seq', 1);setval
--------
(1 row)david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sandy');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'David');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+-------
| Sandy
| David
(2 rows)david=# select currval('tbl_xulie_id_seq');currval
---------
(1 row)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)
b. setval(regclass, bigint, boolean)
b.1 setval(regclass, bigint, true)
david=# truncate tbl_xulie;
TRUNCATE TABLE
david=# select setval('tbl_xulie_id_seq', 1, true);setval
--------
(1 row)david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sandy');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'David');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+-------
| Sandy
| David
(2 rows)
效果同a. setval(regclass, bigint)
b.2 setval(regclass, bigint, false)
方法二:修改序列
修改序列的语法:
1、1
ALTER SEQUENCE name [ INCREMENT [ BY ] increment ][ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ][ START [ WITH ] start ][ RESTART [ [ WITH ] restart ] ][ CACHE cache ] [ [ NO ] CYCLE ][ OWNED BY { table.column | NONE } ]
ALTER SEQUENCE name OWNER TO new_owner
ALTER SEQUENCE name RENAME TO new_name
ALTER SEQUENCE name SET SCHEMA new_schema
实例:
david=# truncate tbl_xulie;
TRUNCATE TABLE
david=# alter sequence tbl_xulie_id_seq restart with 0;
ERROR: RESTART value (0) cannot be less than MINVALUE (1)
david=# alter sequence tbl_xulie_id_seq restart with 1;
ALTER SEQUENCE
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'David');
INSERT 0 1
david=# insert into tbl_xulie values (nextval('tbl_xulie_id_seq'), 'Sandy');
INSERT 0 1
david=# select * from tbl_xulie;id | name
----+-------
| David
| Sandy
(2 rows)david=# select nextval('tbl_xulie_id_seq');nextval
---------
(1 row)
删除序列
语法:
DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
当有表字段使用到PG序列时,不能直接删除。
david=# drop sequence tbl_xulie2_id_seq;
ERROR: cannot drop sequence tbl_xulie2_id_seq because other objects depend on it
DETAIL: default for table tbl_xulie2 column id depends on sequence tbl_xulie2_id_seq
HINT: Use DROP ... CASCADE to drop the dependent objects too.
david=# drop table tbl_xulie2;
DROP TABLE
david=# drop sequence tbl_xulie2_id_seq;
DROP SEQUENCE
说明:对于序列是由建表时指定serial 创建的,删除该表的同时,对应的序列也会被删除。
2、PostgreSQL数据库实现表字段的自增
在使用Mysql时,创建表结构时可以通过关键字auto_increment来指定主键是否自增。但在Postgresql数据库中,虽然可以实现字段的自增,但从本质上来说却并不支持Mysql那样的自增。
Postgresql的自增机制
Postgresql中字段的自增是通过序列来实现的。整体机制是:1、序列可以实现自动增长;2、表字段可以指定默认值。3、结合两者,将默认值指定为自增序列便实现了对应字段值的自增。
Postgresql提供了三种serial数据类型:smallserial,serial,bigserial。它们与真正的类型有所区别,在创建表结构时会先创建一个序列,并将序列赋值给使用的字段。
也就是说,这三个类型是为了在创建唯一标识符列时方便使用而封装的类型。
bigserial创建一个bigint类型的自增,serial创建一个int类型的自增,smallserial创建一个smallint类的自增。
自增方式一示例
使用示例如下:
create table biz_test(id serial PRIMARY KEY,name varchar);
此时生成的表结构为:
aa=# \d biz_testTable "public.biz_test"Column | Type | Modifiers
--------+-------------------+-------------------------------------------------------id | integer | not null default nextval('biz_test_id_seq'::regclass)name | character varying |
Indexes:"biz_test_pkey" PRIMARY KEY, btree (id)
我们可以看到ID字段默认值为nextval(‘biz_test_id_seq’::regclass)。也就是说,在执行创建语句时首先创建了一个以“表名”+"_id_seq"的序列。然后再将该序列赋值给id字段。对应序列的类型为Integer类型。
此时,通过一条insert语句来验证一下是否实现了自增。
aa=# insert into biz_test(name) values('Tom');
INSERT 0 1
执行查询语句查看插入的数据:
aa=# insert into biz_test(name) values('Tom');
INSERT 0 1
aa=# select * from biz_test;id | name
----+------1 | Tom
(1 row)
发送数据的确插入成功,并实现了id的自增。
自增方式二示例
通过上面的示例可以衍生出另外一种实现方式。既然使用默认的三种类型可以完成自增的实现,那么将对应的底层实现进行拆分,是不是也可以实现自增的效果呢?
第一步:创建一个序列
aa=# create sequence biz_test_id_seq;
CREATE SEQUENCE
第二步,创建表结构时将该序列设置为字段的默认值
aa=# create table biz_test(id integer primary key default nextval('biz_test_id_seq'));
CREATE TABLE
这样,同样实现了字段的自增效果。
aa=# \d biz_testTable "public.biz_test"Column | Type | Modifiers
--------+---------+-------------------------------------------------------id | integer | not null default nextval('biz_test_id_seq'::regclass)
Indexes:"biz_test_pkey" PRIMARY KEY, btree (id)
针对第二步,如果建表的时并没有设置该字段为默认值,可以后续添加该字段为自增,使用alter语句来进行修改。
ALTER TABLE ONLY public.biz_test ALTER COLUMN id SET DEFAULT nextval('public.biz_test_id_seq'::regclass);
创建序列的语法
上面创建序列时使用了默认值,如果需要指定序列的起始值、步长等参数,可以使用如下语句进行序列的创建。
CREATE SEQUENCE public.biz_test_id_seqSTART WITH 1INCREMENT BY 1NO MINVALUENO MAXVALUECACHE 1;
上述语法其实已经很明显了,START WITH指定起始值,INCREMENT BY指定增长的步长。
Postgresql查找索引的方法与Mysql也不一样,对应的查询语句是:
select * from pg_indexes where tablename='biz_test';schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+---------------+------------+-----------------------------------------------------------------------public | biz_test | biz_test_pkey | | CREATE UNIQUE INDEX biz_test_pkey ON public.biz_test USING btree (id)
(1 row)
或者:
select * from pg_statio_all_indexes where relname='biz_test';relid | indexrelid | schemaname | relname | indexrelname | idx_blks_read | idx_blks_hit
-------+------------+------------+----------+---------------+---------------+--------------20753 | 20757 | public | biz_test | biz_test_pkey | 0 | 0
(1 row)
关于PostgreSQL数据库实现表字段的自增就讲这么多,在学习该项技术时给我最大的启发就是:实现同一功能的不同技术的横向对比,是拓展多维度解决思路的利器。
扩展
函数
--执行函数
select sequence_reset();
--删除函数(执行完自定义函数后一般给他删除掉,不影响其他值)
drop function public.sequence_reset();
查看的序列是否被数据库中的其他对象引用
pigdb=# SELECT p.relname, a.adsrc FROM pg_class p
JOIN pg_attrdef a on (p.relfilenode = a.adrelid)
WHERE a.adsrc ~ 'shipments_ship_id_seq';relname | adsrc
-----------+--------------------------------------------shipments | nextval('shipments_ship_id_seq'::regclass)
(1 row)
这里检查到 shipments_ship_id_seq 序列被 shipments 引用。你可以把这个序列名替换成任何一个你像查看的序列;或者不添加任何条件查看当前数据库中所有序列的引用。
一次序列删除:
pigdb=# DROP TABLE shipments;
DROP TABLE
pigdb=# DROP SEQUENCE shipments_ship_id_seq;
DROP SEQUENCE
参考链接 :
七、参考资料
PostgreSQL - 序列(Sequence) : https://blog.csdn.net/weixin_39211722/article/details/89349457?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
PostgreSQL官方说明:http://www.postgresql.org/docs/9.2/static/functions-sequence.html
PostgreSQL: 数据迁移之序列问题:http://francs3.blog.163.com/blog/static/40576727201281351925766/
https://blog.csdn.net/hbn1326317071/article/details/84637293
PostgreSQL 序列(SEQUENCE) :
https://www.cnblogs.com/mchina/archive/2013/04/10/3012493.html
postgres的序列(Sequence)的使用相关推荐
- Oracle数据库中序列(SEQUENCE)的用法详解
http://database.51cto.com/art/201108/280742.htm 在Oracle数据库中,什么是序列呢?它的用途是什么?序列(SEQUENCE)其实是序列号生成器,可以为 ...
- oracle初始化序列值,如何修改序列(Sequence)的初始值(START WITH)
Oracle 序列(Sequence)主要用于生成流水号,Oracle EBS系统中是经常用到的.但是,有时需要修改序列初始值(START WITH)时,好多人凭感觉认为:Alter Sequence ...
- mysql添加序列触发器_Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例...
问题:在SQL Server数据库中,有自增列这个字段属性,使用起来也是很方便的.而在Oracle中却没有这个功能,该如何实现呢? 答:在Oracle中虽然没有自增列的说法,但却可以通过触发器(tri ...
- 序列(SEQUENCE)、同义词(SYNONYM)
--============================================= --SQL基础--> 序列(SEQUENCE).同义词(SYNONYM) --========== ...
- Oracle sql创建序列sequence
知道的创建表序列的用途是当建立表的时候,Oracle不像Mysql一样会有自动主键增长AUTO_INCREMENT,所有如果需要主键自动增长的效果,Oracle提供了序列sequence方式. 创建序 ...
- oracle如何实现自增?----用序列sequence的方法来实现
将表t_user的字段ID设置为自增:(用序列sequence的方法来实现) ----创建表 Create table t_user( Id number(6),userid varchar2(2 ...
- oracle 序列缓存的作用,Oracle序列sequence 深入理解
Oracle序列:序列(Sequence)创建.使用.修改.删除,序列(Sequence)是用来生成连续的整数数据的对象.序列常常用来作为主键中增长列,序列中的可以升序生成,也可以降序生成. 语法:创 ...
- oracle 序列 清除,Oracle序列(Sequence)创建、使用、修改、删除
Oracle序列(Sequence)创建.使用.修改.删除 一: 创建序列: 语法: CREATE SEQUENCE sequence_name [START WITH num] [INCREMENT ...
- postgres查询序列_PostgreSQL之序列(Sequence)
PostgreSQL 中的序列是一个数据库对象,本质上是一个自增器.因此,序列在其他同类型数据库软件中以 autoincrment 值的形式存在.在一张表需要非随机,唯一标实符的场景下,Sequenc ...
最新文章
- Android ListView 自定义背景后 滚动时的背景变黑问题
- Android 下载文件并显示进度条
- Qt Linguist手册
- istringstream字符串流,实现类似字符串截取的功能,字符串流中的put,str()将流转换成为字符串string
- (译)Windsor入门教程---第三部分 编写第一个Installer
- [C++11]推荐使用auto的场景
- AngularJS中页面传参方法
- vue 引入html模板,vue单页面用script方式引入 使用模板时报错。 - 社区 - 妙味课堂...
- Javascript预解析、代码执行
- 一个有趣的Java编译问题
- android 判断wifi强弱,Android:通过WifiManager监听Wifi信号强弱
- topaz remask破解版|topaz remask抠图神器5破解版下载
- 微信怎么不支持华为鸿蒙,微信迟迟不加入鸿蒙,华为为何不着急呢?
- 有N个台阶,一步可以走一梯或者两梯,请问有多少种走法
- java反射和反编译
- C++实现rviz 2D Pose Estimate 功能设置机器人初始坐标
- 测试工程师必备测试常识
- Linux运行java的Jar文件
- linux ps stat dls,findbugs 常见问题 及解决方案
- 树莓派搭建nas历程记录