PostgreSQL自增序列手工设置主键+自动生成主键融合使用

场景描述 

      在最近的工作中,遇到了一个自增队列使用的问题,记录一下解决过程和方案。

        文章参考了: PostgreSQL自增序列-主键冲突问题_子木倾然的博客-CSDN博客查询全部序列:select * from pg_class where relowner=(select usesysid from pg_user where usename='postgres') and relkind='S'创建序列CREATE SEQUENCE t_app_app_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9999...PostgreSQL自增序列手工设置主键+自动生成主键融合使用https://blog.csdn.net/qq_23021275/article/details/89396653

      针对某个业务表 (user),包含三列:id 、code、name,其中id列为主键列,使用自增序列方式,目前存在业务功能(用户维护1),在用户维护新增用户保存时,主键通过自增序列自动生成  ,写法如下:

(insert into user(code,name) values('admin','系统管理员') returning id;
--通过自增序列生成id,并且使用returning id 将生成的主键返回

 

        现在需要使用某框架做一个新的用户维护功能(用户维护2),并且两套功能要同时使用,由于框架限制,新增的数据的主键需要在插入数据(insert)之前就得到,这样就无法使用如上SQL来处理了。

        因为两个功能要同时使用,并且用户维护1功能逻辑不能改变,两套功能新增的user数据主键不能冲突。

  解决过程

         第一次尝试

        在用户维护2中,使用序号提前得到下一个序列(假如得到的结果10):

SELECT ,MAX(id)+1 FROM user;

        然后在保存时,将得到的下一个序列值插入到数据库中:

insert into user(id,code,name) values(10,'code11','name11')

        新功能测试好使,但是在一起使用时,出现了问题:在用户维护1中,新增的数据,自增序列生成的主键值,也会生成10,结果与用户维护2新增的数据出现主键冲突。

        问题分析:貌似如下sql并没用把序列的占用值更新,所以10仍然可用。

正确方案

        在获取主键值时,使用如下sql,在获取下一个主键时,及时更新自增序列的当前值,这样用户维护1新增数据时,才会跳过已经获取到的主键,避免主键冲突:

SELECT setval('自增序列名',nextval('自增序列名'),true) FROM user;

注:本来打算使用参考文档中的如下写法来获取主键,但是貌似如下写法也并未更新自增序列的最大号

SELECT setval('自增序列名',MAX(id)+1,true) FROM user;
上一篇:【TPC-DS】trino+S3+hive+postgresql性能测试----生成简单数据验证环境(三)


下一篇:数据库监测故障告警工具(mysql、postgreSql、sqoracle、sqlServer)推荐——WGCLOUD