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

版权声明:本博客可以随便转载,愿意注明出处就注明,不愿意也无所谓,学到就好。 https://blog.csdn.net/yuyongqun/article/details/84186243

@[Anna_1314]@
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;
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 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、插入数据脚本的示例

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

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

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

猜你喜欢

转载自blog.csdn.net/yuyongqun/article/details/84186243
今日推荐