postgresql 按日期动态创建分区表
1、创建主表
CREATE TABLE "public"."tbl_vehicle_statistics" ( "id" serial PRIMARY KEY, "plate_code" varchar(64), "plate_color" int4, "pass_time" timestamp );
2、创建存储过程
create or replace function auto_insert_tbl_vehicle_statistics()
returns trigger as
$BODY$
declare
-- 分区后缀
column_name text := TG_ARGV[0];
yyyymmddHHmmss text := to_char(NEW.pass_time,yyyy-mm-dd hh24:mi:ss);
yyyymmdd text := to_char(NEW.pass_time,yyyymmdd);
yyyymm text := to_char(NEW.pass_time,yyyymm);
isExist boolean;
strSQL text;
startTime text;
endTime text;
begin
--判断对应分区表是否存在
select count(*) INTO isExist from pg_class where relname = (TG_RELNAME||_||yyyymmdd);
--若不存在分区表:
if (isExist = false) then
--创建子分区表
startTime := yyyymm||01 00:00:00;
endTime := date_trunc(month,NEW.pass_time) + interval 1 month;
strSQL := create table if not exists || TG_RELNAME ||_||yyyymmdd||
( CHECK(|| column_name ||>=|| startTime ||
AND || column_name ||< || endTime || )
) INHERITS (||TG_RELNAME||) ; ;
EXECUTE strSQL;
-- 创建索引
strSQL := CREATE INDEX ||TG_RELNAME||_||yyyymmdd||_INDEX_||column_name|| ON
||TG_RELNAME||_||yyyymmdd|| (||column_name||); ;
EXECUTE strSQL;
end if;
-- 插入数据到子分区
strSQL := INSERT INTO ||TG_RELNAME||_||yyyymmdd|| SELECT $1.* ; ;
EXECUTE strSQL USING NEW;
RETURN NULL;
END
$BODY$
language plpgsql;
关于postgreSQL触发器内置的一些变量及其说明:
3、为主表创建触发器
CREATE TRIGGER tbl_vehicle_statistics_trigger BEFORE INSERT ON tbl_vehicle_statistics FOR EACH ROW EXECUTE PROCEDURE auto_insert_tbl_vehicle_statistics(pass_time);
4、测试数据写入
insert into tbl_vehicle_statistics(id,plate_code,plate_color,pass_time) VALUES(1,京A0001,1,to_timestamp(2023-08-07 09:54:00,yyyy-mm-dd hh24:mi:ss));
5、其他
(1)删除触发器
drop trigger tbl_vehicle_statistics_trigger on tbl_vehicle_statistics;
(2)删除存储过程
DROP function auto_insert_tbl_vehicle_statistics();
