PostgreSQL分区表(partitioning)应用实例

项目中有需求要垂直分表,即按照时间区间将数据拆分到n个表中,PostgreSQL提供了分区表的功能。分区表实际上是把逻辑上的一个大表分割成物理上的几小块,提供了很多好处,比如:

查询性能大幅提升

删除历史数据更快

可将不常用的历史数据使用表空间技术转移到低成本的存储介质上

那么什么时候该使用分区表呢?官方给出的指导意见是:当表的大小超过了数据库服务器的物理内存大小则应当使用分区表,接下来结合一个例子具体记录一下创建分区表的详细过程。

创建分区表

首先看一下需求,现在有一张日志表,现在需要按表中的操作时间字段(operation_time)分区,如下图:

这里写图片描述


这里写图片描述

这个需求就是一个典型的按时间创建分区表,首先看一下步骤:

创建父表

创建n个子表,每个子表都是继承于父表

定义一个规则(Rule)或触发器(Trigger),把对主表的数据插入重定向到合适的分区表

如上所示,整体的大步骤就分为以上三个,当然还可以有一些小的优化措施,比如对于每个分区,在关键字字段上创建一个索引等等。首先来看第一步——创建父表。

在创建分区表之前应当先创建一张“父表”,所有分区表都从它继承,这个表中没有数据,也不要在这个表上定义任何检查约束及索引,现在我们就先创建这样一张表,但之前先建一个序列:

CREATE SEQUENCE "public"."t_sys_log_main_id_seq" INCREMENT 1 MINVALUE 1 MAXVALUE 99999999 START 1 CACHE 1; ALTER TABLE "public"."t_sys_log_main_id_seq" OWNER TO "postgres";

接下来创建“父表”,因为是日志表,所以表名命名为“t_sys_log_main”:

CREATE TABLE "public"."t_sys_log_main" ( "id" int4 DEFAULT nextval('t_sys_log_main_id_seq'::regclass) NOT NULL, "account_affiliation_code" varchar(100) COLLATE "default" NOT NULL, "account_affiliation" varchar(50) COLLATE "default" NOT NULL, "operation_time" timestamp(6) NOT NULL, "operation_key" varchar(2) COLLATE "default" NOT NULL, "operation_value" varchar(30) COLLATE "default" NOT NULL, "operation_loginid" varchar(100) COLLATE "default" NOT NULL, "operation_message" varchar(300) COLLATE "default" NOT NULL, "operation_ip" varchar(30) COLLATE "default" NOT NULL ) WITH (OIDS=FALSE) ; COMMENT ON TABLE "public"."t_sys_log_main" IS '系统日志表'; COMMENT ON COLUMN "public"."t_sys_log_main"."account_affiliation_code" IS '帐号所属机构代码'; COMMENT ON COLUMN "public"."t_sys_log_main"."account_affiliation" IS '帐号所属机构'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_time" IS '操作时间'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_key" IS '操作类型(key)'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_value" IS '操作类型(value)'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_loginid" IS '操作帐号'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_message" IS '操作信息'; COMMENT ON COLUMN "public"."t_sys_log_main"."operation_ip" IS '登录地址'; ALTER TABLE "public"."t_sys_log_main" ADD PRIMARY KEY ("id");

运行以上DDL语句创建父表,创建成功后接下来就可以挨个创建分区表了,由于每个分区表都是从父表继承的,所以分区表不会增加任何字段,下面我们按需求创建4张分区子表,分别用于存放9月、10月、11月和12月的日志数据:

create table t_sys_log_y2016m09 (CHECK (operation_time >= DATE '2016-09-01' AND operation_time< DATE '2016-10-01')) INHERITS (t_sys_log_main); create table t_sys_log_y2016m10 (CHECK (operation_time >= DATE '2016-10-01' AND operation_time< DATE '2016-11-01')) INHERITS (t_sys_log_main); create table t_sys_log_y2016m11 (CHECK (operation_time >= DATE '2016-11-01' AND operation_time< DATE '2016-12-01')) INHERITS (t_sys_log_main); create table t_sys_log_y2016m12 (CHECK (operation_time >= DATE '2016-12-01' AND operation_time< DATE '2017-01-01')) INHERITS (t_sys_log_main);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1f0e21dbc1e12b18dd7a887c0b4ad4fa.html