网上之前能找到的例子,都是按数量创建分区子表。

而实际业务中,按日期分区应该是主流,如果照搬按数量创建分区子表的话,感觉不太合用,毕竟实施运维人员也不想动脑子,你居然要求不能频繁执行某个函数,然后又要求多久必需执行它一次……

那么,还是应该搞一个按日期创建分区子表的函数,就显得很有必要了。

前段时间就抽空写了这样一个函数,以后项目上可以直接拿来用。

这个函数可以多次执行,而且不会创建过多的分区子表(估计我有精神洁癖),毕竟可以通过 _end_date参数来规范子表的日期范围嘛,贴出来共享给大家。

注释写得比较啰嗦,我也怕时间久了记不清当初的意图,慢慢看哈。

CREATE OR REPLACE FUNCTION append_partition_table(_partition_tablename VARCHAR, _begin_date DATE, _end_date DATE, _partition_type INT, _gaps INT)
RETURNS void
AS
$BODY$
DECLARE -- 分区表子表名_partition_child_name VARCHAR;-- 循环递增变量ii INT DEFAULT 0;-- 计算得出的,假设的分区字段From的值,对应的日期partition_from_date DATE;-- 计算得出的,假设的分区字段To的值,对应的日期,用于判断是否可以退出循环partition_to_date DATE;
BEGIN-- 功能:不使用分区表插件,为PgSQL内置分区表中,为指定分区主表,按天、按月、按年添加分区--       子表,若不是按[天]分区时,添加的分区子表会比[截止日期]稍大些日期--       在PostgresSQL v14.1中调试通过-- 说明:-- 1、使用该存储过程时,只是按指定规则生成分区子表的表名并创建,并不能判断该子表名是否--     为分区主表的子表,即,若该子表名已存在则不建表,若该子表名不存在则创建成指定分区--     主表的分区子表-- 2、分区子表名未加双引号,不区分大小写,默认为小写--     分区表子表名 = 主表名 + 分隔符 + 年月日(或者年月,或者年),如,log_all_202001或者log_all_20200201-- 3、分区子表将与分区主表在同一个Schema中,本存储过程并不做特殊处理---- 4、本存储过程自动创建的分区子表,是range分区表,请自行建好主表,建主表Demo如下:-- CREATE TABLE queue (--   qid varchar(50) NOT NULL,--   pati_id varchar(50) NULL,--   pati_name varchar(50) NULL,--   serial_number varchar(100) NULL,--   stateid int4--   validdate date,--   PRIMARY KEY (qid, validdate)-- )-- PARTITION BY range (--   validdate-- );-- 5、因为没找到如何查找现有分区子表的From和To的值,所以只好强行建表了,有知道的麻烦告诉我,谢谢 -- 调用Demo1:SELECT append_partition_table('operation_log', '2021-02-11', '2021-08-11', 0, 1);-- 调用Demo2:SELECT append_partition_table('public.operation_log', '2021-02-11', '2021-08-11', 1, 1);-- 参数:_partition_tablename:创建分区子表的主表的名称, 注意确认表名中是否需要包含Schema名,分区
--       分区子表将与分区主表在同一个Schema中
-- 参数:_begin_date:创建分区表的开始日期
-- 参数:_end_date:创建分区表的截止日期
-- 参数:_partition_type:分区类型[0按天分区,1按月分区,2按年分区]
-- 参数:_gaps:分区间隔,如果分区类型为0,则表示每个分区的间隔为 gaps天
--       如果分区类型为1,则表示每个分区的间隔为 gaps月
--       如果分区类型为2,则表示每个分区的间隔为 gaps年-- 输出调试信息RAISE NOTICE '_partition_type=[%]', _partition_type;RAISE NOTICE '_gaps=[%]', _gaps;-- _partitiontype 只接收0/1/2三种值IF _partition_type not in (0,1,2) THENRAISE EXCEPTION 'The Parameter [_partition_type] is incorrect. Only 0, 1, and 2 are supported!!! '; END IF;partition_from_date := _begin_date::DATE;partition_to_date := _begin_date::DATE;-- 开始循环,判断并自动分区WHILE (partition_to_date <= _end_date) LOOP-- 根据[类型入参],生成准备创建的分区子表的表名IF (_partition_type = 0) THEN-- 每个分区按天递增, 递增gaps天, 计算得到From和To的值,并按From的值生成分区子表名中日期的数字部分partition_from_date = _begin_date::DATE+ CONCAT((i)*_gaps,' day')::INTERVAL;partition_to_date = _begin_date::DATE+ CONCAT((i+1)*_gaps,' day')::INTERVAL;_partition_child_name := to_char(partition_from_date::DATE, 'yyyymmdd');ELSEIF (_partition_type = 1) THEN-- 每个分区按月递增, 递增gaps月, 计算得到From和To的值,并按From的值生成分区子表名中日期的数字部分partition_from_date := date_trunc('MONTH', _begin_date::DATE)+ CONCAT((i)*_gaps, ' MONTH')::INTERVAL;partition_to_date := date_trunc('MONTH', _begin_date::DATE)+ CONCAT((i+1)*_gaps, ' MONTH')::INTERVAL;_partition_child_name := to_char(partition_from_date::DATE, 'yyyymm');ELSE-- 每个分区按年递增, 递增gaps年, 计算得到From和To的值,并按From的值生成分区子表名中日期的数字部分partition_from_date := date_trunc('YEAR', _begin_date::DATE) + CONCAT((i)*_gaps,' YEAR')::INTERVAL;partition_to_date := date_trunc('YEAR', _begin_date::DATE) + CONCAT((i+1)*_gaps,' YEAR')::INTERVAL;_partition_child_name := to_char(partition_from_date::DATE, 'yyyy');END IF;-- 拼接分区表子表名,分区表子表名 = 主表名 + 分隔符 + 年月日(或者年月,或者年)_partition_child_name := _partition_tablename||'_'||_partition_child_name;-- 输出调试信息RAISE NOTICE 'partition_from_date=[%]', partition_from_date;RAISE NOTICE 'partition_to_date=[%]', partition_to_date;RAISE NOTICE '_partition_child_name=[%]', _partition_child_name;-- 快速判断某个表是否存在 -- IF (to_regclass(_partition_child_name) is null) THEN-- END IF;--     CREATE TABLE IF NOT EXISTS  _partition_child_name
--      PARTITION OF _partition_tablename
--      FOR VALUES FROM (partition_from_date) TO (partition_to_date);-- 输出调试信息RAISE NOTICE 'Run SQL: CREATE TABLE IF NOT EXISTS % PARTITION OF % FOR VALUES FROM (''%'') TO (''%'') WITH (fillfactor=99);', _partition_child_name, _partition_tablename, partition_from_date, partition_to_date;-- 执行SQL语句,判断指定的表名是否存在,若不存在则创建成指定分区主表的分区子表-- [fillfactor=99]也是我的精神洁癖,会浪费1%的磁盘空间,感觉不爽的朋友请自行去掉execute format('CREATE TABLE IF NOT EXISTS %s PARTITION OF %s FOR VALUES FROM (''%s'') TO (''%s'') WITH (fillfactor=99);',_partition_child_name, _partition_tablename, partition_from_date, partition_to_date);RAISE NOTICE 'Run SQL OK!';-- 递增变量i := i + 1;END LOOP; -- End WhileEND;
$BODY$LANGUAGE plpgsql VOLATILE

测试:

SELECT append_partition_table('kysoft.log_all', '2020-02-01', '2020-02-09', 0, 3);

执行结果(意思一下,不贴图了,中间三个表是上面SQL语句建出来的,另两个是之前建的):

Table Name|schema

log_all_202001    kysoft
log_all_20200201    kysoft
log_all_20200204    kysoft
log_all_20200207    kysoft
log_all_his    kysoft

另外,因为没找到如何查找现有分区子表的From和To的值,所以只好强行建表了,有知道的麻烦告诉我,谢谢!

PostgreSQL/pgsql自动添加分区子表相关推荐

  1. PostgreSQL:创建自增序列id,分区表,分区表子表

    文章目录 1)创建自增序列seq 2)创建分区表主表 3)创建分区表子表 4)分区表数据插入 5)分区表查询 1)创建自增序列seq CREATE SEQUENCE if not exists pub ...

  2. excel中提取月份_在Excel中自动添加月份表

    excel中提取月份 Set up a Master sheet in your workbook, and add month sheets automatically, based on that ...

  3. PostgreSQL 分区表性能优化-分区键

    目录 前言 优化过程 数据库版本 总体思路 分区键 前言 近期优化SQL的次数越来越多了,优化的思路可以从SQL结构.执行计划.统计信息.执行计划缓存.索引合理性(数据离散度.联合索引等).程序的数据 ...

  4. linux自动创建分区,shell编程 自动创建分区

    用shell脚本自动添加分区,已实现功能如下: 1.检查扩展分区是否,且是否可以添加,如果可以则把所有的剩余空间设置为扩展分区 2.当扩展分区存在,则输入要添加的分区大小,仅接受大于1的正整数 代码如 ...

  5. 利用Topshelf搭建Windowns服务实现定期自动添加数据逻辑和原理

    一.Topshelf基本配置 using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  6. mysql 表分区、按时间函数分区、删除分区、自动添加表分区

    mysql 表分区的几种方式: RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区. LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进 ...

  7. mysql按照时间自动创建分区表_mysql 表分区、按时间函数分区、删除分区、自动添加表分区...

    mysql 表分区的几种方式: RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区. LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进 ...

  8. mysql 主表存hash和子表的名字_【mysql】mysql分表和表分区详解

    为什么要分表和分区? 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能 ...

  9. Access和SQL server开启表间关系,并实现更新或删除母表数据自动更新或删除子表数据...

    1.Access开启表间关系,并实现删除母表数据自动删除子表数据: 在Tables等界面 - > 右键 - > Relationships... -> 弹出Relationships ...

最新文章

  1. LeetCode 42. Trapping Rain Water--算法题--c++解法
  2. httpHandlers使用和问题
  3. 每日一皮:这就是成都马拉松???...
  4. 高中生活--第1篇--荣辱一身,悲尽兴来
  5. 两个瓶子水怎样一样多_同事每天比我多睡两个小时!省下70万买了地铁站附近房子 杭州姑娘却感叹买房时一定是脑子进了水……...
  6. php 读取或导出到Excel / CSV (附utf8、gbk 编码转换)
  7. 10个最佳jQuery Lightbox效果插件收集
  8. python deque_python中deque类详解
  9. (转载)js对象原来也有类、实例属性和原型属性
  10. lamp mysql数据库设置_LAMP环境搭建图形界面配置MySQL数据库
  11. mysql中文显示问号,不能识别中文的解决方案
  12. GDB中打印pthread_internal_t的方法
  13. html返回顶部动画,基于JavaScript实现回到页面顶部动画代码
  14. 简单详细的OD破解教程(转)
  15. IP地址、子网掩码、网络数、主机数、广播地址及其计算方法
  16. 第一篇博客--大学成长指南
  17. 光棍.com市场推广策划书(爆笑)
  18. Arnold Denoise流程
  19. Go 学习笔记(83)— 编码规范及常用开发技巧
  20. 当原图片加载失败时,如何让图片加载上我们默认给的图片

热门文章

  1. 6个面试的经典英文问题
  2. 身体健康,从情绪健康开始
  3. 魔兽怀旧服wowlua api获取人物坐标信息
  4. Windows网络编程 c语言 报错:[Error] ‘bzero‘ was not declared in this scope
  5. 如何让 AI 像人类一样存有大量记忆?
  6. 【Python】猎聘网招聘数据爬虫(Python网络爬虫课设简要)
  7. python计算机二级证书含金量到底高不高?
  8. CGAL笔记之单元格复合体和多面体篇—三维多面体曲面
  9. JS三元运算符判断多个条件。
  10. 中国移动ARM芯片CM32M101A资料下载工具tool下载链接