postgreSQL数据自动分区分表

postgreSQL数据自动分区分表

今天客户反馈说,系统有个模块访问有点慢。于是乎点进去瞅一瞅;发现有一个表是存储同步过来的实时数据;数据量已经到了千万的级别了。因此想说给这个表做个分区。这个项目用的数据库是PG;但由于我之前基本都是在用mysql的数据库;所以度年了一下PG的分表。网络上还是有蛮多的。发帖只是为了做个笔记,便于自己以后查阅!!!

分表过程可以参考:

PostgreSQL分区表(Table Partitioning)应用

贴上代码

-- my_table为要分区的源表
-- create_time 为分表字段(此处,根据这个时间字段,按年分表)
CREATE TRIGGER insert_my_table_trigger
BEFORE INSERT
ON my_table
FOR EACH ROW
EXECUTE PROCEDURE auto_insert_into_my_table('create_time');


-- 触发器函数
CREATE OR REPLACE FUNCTION auto_insert_into_my_table()
  RETURNS trigger AS 								-- 触发器函数必须是无参的,并且返回值为trigger
$$
DECLARE
    colunmName		text;			-- 父表中用于分区的时间字段的名称[必须首先初始化!!!],此处是create_time
    yearStr 		varchar(6);		-- 'YYYY'字串,用做分区子表的后缀
    tbExist 		boolean;		-- 分区子表 是否存在标志位
    stm 			text;			-- 分区开始时间(一年的01月01日)
    etm 			text;			-- 分区截止时间(一年的12月31日)
    sqlStr 			text;			-- sql语句字符串变量
    
BEGIN
	-- 当一个PL/pgSQL 函数作为一个触发器被调用时,系统自动在最外层的块创建一些[特殊的变量]。
    -- 调用前,必须首先初始化(时间字段名):colunmName [直接从调用参数中获取!!!];
	-- TG_ARGV:为[特殊的变量]之一,数据类型是text类型的数组。
	-- 表示CREATE TRIGGER命令传给触发器过程的所有参数。
	-- 下标从0开始。TG_ARGV[0]表示第一个参数,TG_ARGV[1]表示第二个参数,以此类推。 
	-- 如果下标小于0或大于等于CREATE TRIGGER命令传给触发器过程的参数的个数,将会返回一个空值。
	-- 此处取第一个参数,既create_time
    colunmName := TG_ARGV[0];
   
    -- 判断对应分区表 是否已经存在?
	-- NEW:为[特殊的变量]之一;数据类型是RECORD。
	-- 对于行级触发器,它存有INSERT或UPDATE操作产生的新的数据行。
    EXECUTE 'SELECT NEW.'||colunmName INTO sqlStr;
    yearStr := to_char(sqlStr::timestamp , 'YYYY');
	-- pg_class:postgreSQL内部表;记录表和几乎所有具有列或者像表的东西
	-- TG_TABLE_NAME:数据类型是name,表示触发器作用的表的名字。它与变量TG_RELNAME的作用是一样的。
    select count(*) INTO tbExist from pg_class where relname = (TG_TABLE_NAME||'_'||yearStr);
 
    -- 若不存在, 则插入前需 先创建子分区
    IF ( tbExist = false ) THEN  
        -- 创建子分区表
        stm := yearStr||'-01-01 00:00:00.000';
        etm := to_char(stm::timestamp + interval '1 year', 'yyyy-MM-dd HH24:mi:ss.ms');
        sqlStr := 'CREATE TABLE IF NOT EXISTS '||TG_TABLE_NAME||'_'||yearStr||
                  ' ( 
											CHECK('||colunmName||'>='''|| stm ||''' AND '||colunmName||'< '''|| etm |''' )
                     ) INHERITS ('||TG_TABLE_NAME||') ;'  ;  
        EXECUTE sqlStr;
 
        -- 创建索引
        sqlStr := 'CREATE INDEX IDX_'||TG_TABLE_NAME||'_'||yearStr||'_'||colunmName||' ON '
                  ||TG_TABLE_NAME||'_'||yearStr||' ('||colunmName||');' ;
        EXECUTE sqlStr;
       
    END IF;
 
    -- 插入数据到对应的分表中
    sqlStr := 'INSERT INTO '||TG_TABLE_NAME||'_'||yearStr||' SELECT NEW.*' ;
    EXECUTE sqlStr;
    RETURN NULL; 
END
$$ LANGUAGE plpgsql;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值