psql按月分表之觸發器自動建表
阿新 • • 發佈:2018-12-22
@[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程式碼中直接可以不用關心如何去分割槽或者插入,和訪問普通的資料庫表操作沒有區別。