PostgreSQL PG序列 与 序列是否可以绑定到多个表的疑问

2021-07-01 00:00:00 序列 多个 设置 插入 绑定

近有点累,想休息几天,散散心,下一次更新在周五。







POSTGRESQL 表的自增类似ORACLE 的做法, 当然这不是说就是一样,只是类似.  PostgreSQL的序列本身是需要创建的类似于一个数字序列的生成器,表中字段需要通过设置来获取序列给出的值, one by one .

select c.relname FROM pg_class c WHERE c.relkind = 'S';

通过pg_class 来对我们当前的数据库中的序列进行查找


与Oracle 不同的是PostgreSQL 的基本对于序列的使用是一个表一个序列的方式.

这里对于POSTGRESQL 创建序列有几个需要了解和知道的地方

1  postgresql 的序列是可以有类型的

2  postgresql 的学是有range的,也就是可以设置大和小的值

3  postgresql 的序列是可以循环使用的达到了大值后,如果设置了循环是可以从头开始的

4  cache 这个是PG对于自增序列的一个友好和快速数据分配和插入的支持,我们可以

create sequence id_seq as bigint increment 1 minvalue 100 NO MAXVALUE start 100 cache 1000 cycle;


owner by  主要是将自增与数据库表的列建立关系,如果这列删除则自增也会被删除.

创建一个表

create table seq (id int primary key, name varchar(10));

alter sequence id_seq owned by  seq.id;

把刚才建立的序列挂载到表中.通过 nextval 函数来调用序列.



由于我们之前设置的初始值是100 所以这边通过nextval 的个值是100

select * from pg_sequences;

并且通过pg_sequences 来查看当前的schema中的所有的sequence 的信息,这点其实比ORACLE 的sequences 要好(11G).


如果在使用序列的时候需要获得序列的select currval('id_seq');  当前的已经使用的后一个值,类似有些数据库的last value .


另外还有一些常见的问题

1   我truncate 表后, 序列有变化吗?

2   我可以多个表绑定一个序列吗

3   我删除数据后,序列会有变化吗

4   我事务得到分配的序列值后,如果回滚了我的序列值应该在那个位置?



truncate 表后,并没有讲序列的值进行任何改变,在此插入数据库还是会继续累加上一次的值.


说完这些其实就有一个问题了, ORACLE 当中的序列是可以一个序列绑定到多个表的上来进行序列的值的给出. 那么POSTGRESQL 本身是不是可以这样做,我们来实验一下.


我产生一个序列,通过这个序列绑定 几个表看看情况如何


create sequence id_seq as bigint increment 1 minvalue 100 NO MAXVALUE start 100 cache 1000 cycle;

 create table seq (id int primary key, name varchar(10));

alter sequence id_seq owned by  seq.id

insert into seq (id,name) values (nextval('id_seq'),'1');

select * from seq;

 create table seq2 (id int primary key, name varchar(10));

 create table seq3 (id int primary key, name varchar(10));

alter sequence id_seq owned by  seq2.id;

insert into seq2 (id,name) values (nextval('id_seq'),'1');

select * from seq2;

alter sequence id_seq owned by  seq3.id;

insert into seq3 (id,name) values (nextval('id_seq'),'1');

select * from seq3;


从上面的测试看,我们的可以明显的看到一个问题,如果一个序列挂多个表,则对于序列来说,是顺序性的,并不能做到一个序列分别对每个表进行分别的计数.


而上面的明显的在绑定第二个表后,插入数变为了1100 的主要的原因是cache ,cache 中设置的数字决定了你绑定下一个表的基数,也就是插入数据后个数据起始值.


如 cache 是1000 , 则个表当前的插入值是  100, 我们在绑定第二个表后,在此插入值是 1100, 而在绑定第三个表,插入值是 2100. 


所以POSTGRESQL 本身的序列 sequense 只能一个序列一个表使用,不建议多个表使用一个序列.



相关文章