postgres 序列 SEQUENCE

前言

postgres简单使用navicat备份数据库时,若存在自增字段会导致数据备份失败

序列相关查询

获取库中的序列

sql 复制代码
SELECT table_name, column_name, substr(column_default, 10,"length"(column_default)-21) AS serial_sequence
FROM information_schema.columns
WHERE table_schema = 'public'
AND column_default LIKE 'nextval%' 

获取序列信息

sql 复制代码
SELECT * FROM information_schema.sequences

另外一种查询方式

sql 复制代码
-- 查看 r =普通表, i =索引,S =序列,v =视图,m =物化视图, c =复合类型,t = TOAST表,f =外部表 
select * from pg_class where relkind='S';

获取序列值

sql 复制代码
SELECT currval('test_one_id_seq')

上述代码中currval()中输入为序列名称。

此时会有两种结果,如果表没有数据,或者序列为1时,会报错!!!

正常显示

根据表和字段获取序列

sql 复制代码
SELECT pg_get_serial_sequence('test_one', 'id');

pg_get_serial_sequence(表名,字段) 如果是存在序列 返回序列名,否则返回null

存在:

不存在:

序列操作

创建序列

圆规正传,回到我们开头的问题,提示我们关系不存在,那么我们只要创建关系即可

sql 复制代码
--简单创建
CREATE SEQUENCE "public".序列名称;
--自定义创建
CREATE SEQUENCE "public".序列名称 INCREMENT 1 MINVALUE 1 MAX 999999999 STAER 1 CACHE 1;
--参数说明
--INCREMENT 1  代表每次新增序列加1
--MINVALUE 1  代表最小值为 1 NO MINVALUE 代表则不设最小值
--MAXVALUE 9999999 代表最大值为 99999999 NO MAXVALUE 代表不设置最值
--START 1 代表初始值为1
--CACHE 1 设置缓存区

创建完成,如下图

重新导入,导入完成

虽然导入完成了但是存在一个bug,当我们重新插入数据是大概率会遇到id已存在的错误,

我们打开导出的sql查看内容

发现导入数据是id的值是已填的,这样不会触发id的自增效果,所以序列的初始值一直是0的状态 所以为了引起不必要的bug,我们需要把序列更新成id的最大值即可。

修改序列值

下方设置序列值为1000,则下一次插入的值为1001

sql 复制代码
SELECT setval('序列名', 1000);

另外的更新方式

sql 复制代码
ALTER SEQUENCE 序列名 RESTART WITH 1000;

删除

sql 复制代码
--删除 
drop sequence xxx_no_seql;

函数更新序列值

上方提供了单个表更新序列的方法,如果遇到1个表还行哈,但是遇到多个表,假如100个表,我们能一个一个的修改序列的值嘛,经过我历时两年半的学习,使用函数可以完美解决这个问题,下面是我历时年半的成果!

sql 复制代码
CREATE OR REPLACE FUNCTION "public"."reset_all_sequences_max"("p_schema_name" text)
  RETURNS "pg_catalog"."varchar" AS $BODY$
DECLARE
		v_max_value bigint;
		v_seq RECORD;
BEGIN
  -- 获取所有表
    FOR v_seq IN
    SELECT
    substr(column_default, 10,"length"(column_default)-21) AS sequence_name,
    "table_name",
    "column_name"
    FROM information_schema.columns
    WHERE column_default LIKE 'nextval%'
    AND table_schema = p_schema_name
    LOOP
        IF v_seq.sequence_name IS NOT NULL THEN	
            -- 获取表字段的最大值
            EXECUTE 'SELECT MAX(' || quote_ident(v_seq.column_name) || ') FROM ' || quote_ident(p_schema_name) || '.' || quote_ident(v_seq.table_name)
            INTO v_max_value;
                IF v_max_value IS NOT NULL THEN
                    -- 重置序列的值为表字段的最大值
                    EXECUTE 'SELECT setval(''' || v_seq.sequence_name || ''', ' || v_max_value || ')';
                ELSE
            END IF;
        END IF;
    END LOOP;
    RETURN 'All sequences reset successfully for table';

    EXCEPTION
        WHEN OTHERS THEN
            RETURN 'An error occurred: ' || SQLERRM;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

选择函数

p_schema_name的值传入指定模式即可,本文章使用模式为 pubilc

执行函数

执行完成!

第二种方式,从创建时解决问题,不过这个方法会使原始库的自增id加1

sql 复制代码
SELECT 'CREATE SEQUENCE '||substr(column_default, 10,"length"(column_default)-21)||' INCREMENT 1 START '|| nextval(substr(column_default, 10,"length"(column_default)-21))||';'
FROM information_schema.columns
WHERE table_schema = 'public'
AND column_default LIKE 'nextval%' 

只需要导出结果,然后在迁移前备份即可

nextval() 可以换成 currval() 使用currval方法有序列值为空引起报错风险,可以先currval报错了就用nextval!!! 闲时记录,如有问题请予以指正!!!

相关推荐
鼠鼠我捏,要死了捏18 小时前
PostgreSQL性能优化实践指南:从原理到实战
postgresql·performance·tuning
云游19 小时前
利用外部Postgresql及zookeeper,启动Apache Dolphinscheduler3.1.9
分布式·postgresql·zookeeper·apache·工作流任务调度
__风__2 天前
PostgreSQL kv(jsonb)存储
数据库·postgresql
九皇叔叔2 天前
【7】PostgreSQL 事务
数据库·postgresql
ldj20204 天前
2025 Centos 安装PostgreSQL
linux·postgresql·centos
坤坤不爱吃鱼5 天前
【MySQL\Oracle\PostgreSQL】迁移到openGauss数据出现的问题解决方案
mysql·postgresql·oracle
行星0085 天前
PostgreSQL大表创建分区实战
数据库·postgresql
heart000_116 天前
拯救海量数据:PostgreSQL分区表性能优化实战手册(附压测对比)
数据库·postgresql·性能优化
忧愁的锅盖儿16 天前
PostgreSQL(二十七)索引内部结构
数据库·postgresql
静听山水18 天前
PostgreSQL/Hologres 外部数据包装器系统表 pg_foreign_data_wrapper 详解
数据库·postgresql