psql按月分表之触发器自动建表

1、创建主表
通过主表定义好表的结构,需要一个分表的关键字,比如下面的date_key,分表的时候会根据这个字段所在的表的范围决定插入到哪张分区表中。

drop table if exists tbl_partition;
CREATE TABLE tbl_partition
(
  date_key date,
  hour_key smallint
);

2、 函数用来计算某一天所在月的1号

CREATE OR REPLACE FUNCTION get_month_first_day(in in_date date, out out_date text)
AS $$
BEGIN
  SELECT to_char(in_date, 'YYYY_MM') || '_01' INTO out_date;
END;
$$
LANGUAGE plpgsql;

3、定义触发器
自动建表的触发器实现,当插入一条数据时根据date_key字段的值判断是否需要建表

CREATE OR REPLACE FUNCTION tbl_partition_trigger()
  RETURNS TRIGGER AS $$
DECLARE month_text TEXT;
        this_month_first_day_text TEXT;
        next_month_first_day_text TEXT;
        insert_statement TEXT;
        --real_table_name TEXT NOT NULL := 'tbl_partition';
        --check_col_name TEXT NOT NULL := 'date_key';
BEGIN
  SELECT to_char(NEW.date_key, 'YYYY_MM') INTO month_text;
  SELECT get_month_first_day(NEW.date_key) INTO this_month_first_day_text;
  SELECT to_char(to_date(this_month_first_day_text,'YYYY-MM-DD') + interval '1 month', 'YYYY-MM-DD') INTO next_month_first_day_text;
  insert_statement := 'INSERT INTO tbl_partition_' || month_text || ' VALUES ($1.*)';
  EXECUTE insert_statement USING NEW;
  RETURN NULL;
  EXCEPTION
  WHEN UNDEFINED_TABLE
    THEN
      --建表
      EXECUTE
      'CREATE TABLE IF NOT EXISTS tbl_partition_'
      || month_text
      || '(CHECK (date_key >= '''
      || this_month_first_day_text
      || ''' and date_key < '''
      || next_month_first_day_text
      || ''')) INHERITS (tbl_partition)';
      RAISE NOTICE 'CREATE NON-EXISTANT TABLE tbl_partition_%', month_text;
      --创建索引
      EXECUTE
      'CREATE INDEX tbl_partition_date_key_'
      || month_text
      || ' ON tbl_partition_'
      || month_text
      || '(date_key)';
      --创建主键
      EXECUTE
      'ALTER TABLE tbl_partition_' 
      || month_text 
      || ' ADD CONSTRAINT tbl_partition_' 
      || month_text 
      || '_pkey PRIMARY KEY (date_key, hour_key)';
      EXECUTE insert_statement USING NEW;
      RETURN NULL;
END;
$$
LANGUAGE plpgsql;

4、挂载分区Trigger
即将定义的触发器和主表进行关联起来

CREATE TRIGGER insert_tbl_partition_trigger
BEFORE INSERT ON tbl_partition
FOR EACH ROW EXECUTE PROCEDURE tbl_partition_trigger();

5、设置constraint_exclusion
    constraint_exclusion 的含义是:当PG生产执行计划时是否考虑表上的约束,这个参数有三个选项 “off,on,partition”。默认参数为 off, 意思不使用表上的 constraint 来生成计划;如果设置成 on,则对所有表上的 constraint生效;建议设置成partition,只对分区表生效,从而避免扫描所有分区。

set constraint_exclusion = partition;

6、插入数据脚本的示例

INSERT INTO tbl_partition
values('2018-12-01','12'),('2017-12-03','13'),('2018-11-03','2'),('2017-12-02','3');

7、部分截图效果
在这里插入图片描述

之后随便插入一条数据会根据数据的date_key决定插入到哪个月分区表中区,在java代码中直接可以不用关心如何去分区或者插入,和访问普通的数据库表操作没有区别。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值