圈子推荐
查看所有吧>>
活跃用户
    通过触发器实现自动分区

    针对oracle的自动分区,pg数据库默认是没有的,同理在vastbase和atlasdb中也可以通过触发器实现

    CREATE OR REPLACE FUNCTION auto_insert_into_tbl_partition()

      RETURNS trigger AS

    $BODY$

    DECLARE

        time_column_name     text ;            -- 父表中用于分区的时间字段的名称[必须首先初始化!!]

        curMM         text;        -- 'YYYYMM'字串,用做分区子表的后缀

        isExist         boolean;        -- 分区子表,是否已存在

        startTime         text;

        endTime        text;

        strSQL          text;    

    BEGIN

        -- 调用前,必须首先初始化(时间字段名):time_column_name [直接从调用参数中获取!!]

        time_column_name := TG_ARGV[0];   

        -- 判断对应分区表 是否已经存在?

        EXECUTE 'SELECT $1.'||time_column_name INTO strSQL USING NEW;

        curMM := to_char( strSQL::timestamp , 'YYYYMMDD' );

        select count(*) INTO isExist from pg_tables where tablename = (TG_RELNAME||'_'||curMM) and schemaname='zljtest'; 

        -- 若不存在, 则插入前需先创建子分区

        IF ( isExist = false ) THEN  

            -- 创建子分区表

            startTime := curMM||' 00:00:00.000';

            endTime := to_char( startTime::timestamp + interval '1 day', 'YYYY-MM-DD HH24:MI:SS.MS');

            strSQL := 'CREATE TABLE IF NOT EXISTS '||'zljtest.'||TG_RELNAME||'_'||curMM||

                      ' ( CHECK('||time_column_name||'>='''|| startTime ||''' AND '

                                 ||time_column_name||'< '''|| endTime ||''' )

                              ) INHERITS ('||'zljtest.' || TG_RELNAME||') ;'  ;  

            EXECUTE strSQL;

            -- 创建索引

            strSQL := 'CREATE INDEX '||TG_RELNAME||'_'||curMM||'_INDEX_'||time_column_name||' ON '

                      ||'zljtest.'||TG_RELNAME||'_'||curMM||' ('||time_column_name||');' ;

            EXECUTE strSQL;      

        END IF; 

        -- 插入数据到子分区!

        strSQL := 'INSERT INTO '||'zljtest.'||TG_RELNAME||'_'||curMM||' SELECT $1.*' ;

        EXECUTE strSQL USING NEW;

        RETURN NULL; 

    END

    $BODY$

      LANGUAGE plpgsql;

     

    CREATE TRIGGER insert_tbl_partition_trigger

      BEFORE INSERT

      ON tbl_partition

      FOR EACH ROW

      EXECUTE PROCEDURE auto_insert_into_tbl_partition('gather_time');


    • 分享到:
    排序方式:回复时间 共有3条评论

    舀一瓢数据 发表于 03月09日 17:22 1 楼

    因为这个触发器继承方式可能会影响到到性能,也可以考虑通过其他插件去实现

    | 回复

    不用管我 发表于 03月09日 17:23 2 楼

    回复@舀一瓢数据 :这个针对迁移和数据兼容性,6~

    | 回复

    黄港 发表于 03月16日 10:12 3 楼

    oracle间隔分区也可以吗

    | 回复