Postgresql - Table Partitioning (五)

表继承
虽然内置的声明性分区适用于大多数常见的用例,但在某些情况下,更灵活的方法可能是有用的。分区可以使用表继承来实现,它允许声明性分区不支持的多个特征

While the built-in declarative partitioning is suitable for most common use cases, there are some circumstances where a more flexible approach may be useful. Partitioning can be implemented using table inheritance, which allows for several features which are not supported by declarative partitioning, such as:
  • Partitioning enforces a rule that all partitions must have exactly the same set of columns as the parent, but table inheritance allows children to have extra columns not present in the parent.
  • Table inheritance allows for multiple inheritance.
  • Declarative partitioning only supports list and range partitioning, whereas table inheritance allows data to be divided in a manner of the user's choosing. (Note, however, that if constraint exclusion is unable to prune partitions effectively, query performance will be very poor.)
  • Some operations require a stronger lock when using declarative partitioning than when using table inheritance. For example, adding or removing a partition to or from a partitioned table requires taking an ACCESS EXCLUSIVE lock on the parent table, whereas a SHARE UPDATE EXCLUSIVE lock is enough in the case of regular inheritance.

如何使用表继承:
1. 创建“主”表。普通表,不能是分区表。
所有分区都将从该表继承。不要在该表上定义任何检查约束,对定义任何索引或唯一约束都没有意义。
CREATE TABLE measurement ( city_id int not null, logdate date not null, peaktemp int, unitsales int);

2. 创建多个“子”表,每个表从主表继承。
通常,这些表不会向从主继承的集合添加任何列。正如声明性分区一样,这些分区在各个方面都是正常的PostgreSQL表(或外部表)。
CREATE TABLE measurement_y2018m01 () INHERITS (measurement);
......
CREATE TABLE measurement_y2018m12 () INHERITS (measurement);

3. 将非重叠表约束添加到分区表中。
定义每个分区中允许的键值。确保约束保证在不同分区中允许的键值之间没有重叠。

CREATE TABLE measurement_y2018m01 ( CHECK ( logdate >= DATE '2018-01-01' AND logdate < DATE '2018-02-01' )) INHERITS (measurement);......CREATE TABLE measurement_y2019m01 ( CHECK ( logdate >= DATE '2019-01-01' AND logdate < DATE '2019-02-01' )) INHERITS (measurement);

4. 索引
CREATE INDEX measurement_y2018m01_logdate ON measurement_y2018m01 (logdate);
......
CREATE INDEX measurement_y2018m12_logdate ON measurement_y2018m12 (logdate);

5. We want our application to be able to say INSERT INTO measurement ... and have the data be redirected into the appropriate partition table.

数据只添加到最新的分区
CREATE OR REPLACE FUNCTION measurement_insert_trigger()RETURNS TRIGGER AS $$BEGIN INSERT INTO measurement_y2008m01 VALUES (NEW.*); RETURN NULL;END;$$LANGUAGE plpgsql;

After creating the function, we create a trigger which calls the trigger function:
CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();
****************
可能需要插入数据并让服务器自动定位要添加行的分区,用更复杂的触发器函数来实现这一点
CREATE OR REPLACE FUNCTION measurement_insert_trigger()RETURNS TRIGGER AS $$BEGIN IF ( NEW.logdate >= DATE '2006-02-01' AND NEW.logdate < DATE '2006-03-01' ) THEN INSERT INTO measurement_y2006m02 VALUES (NEW.*); ELSIF ( NEW.logdate >= DATE '2006-03-01' AND NEW.logdate < DATE '2006-04-01' ) THEN INSERT INTO measurement_y2006m03 VALUES (NEW.*); ... ELSIF ( NEW.logdate >= DATE '2008-01-01' AND NEW.logdate < DATE '2008-02-01' ) THEN INSERT INTO measurement_y2008m01 VALUES (NEW.*); ELSE RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; END IF; RETURN NULL;END;$$LANGUAGE plpgsql;

The trigger definition is the same as before.
While this function is more complex than the single-month case, it doesn't need to be updated as often, since branches can be added in advance of being needed.

*************************
将插入重定向到适当的分区表的另一种方法是在主表上设置规则

CREATE RULE measurement_insert_y2006m02 ASON INSERT TO measurement WHERE ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' )DO INSTEAD INSERT INTO measurement_y2006m02 VALUES (NEW.*);...CREATE RULE measurement_insert_y2008m01 ASON INSERT TO measurement WHERE ( logdate >= DATE '2008-01-01' AND logdate < DATE '2008-02-01' )DO INSTEAD INSERT INTO measurement_y2008m01 VALUES (NEW.*);

***************************
6. Ensure that the  constraint_exclusion  configuration parameter is not disabled in  postgresql.conf


维护分区:

# 删分区
DROP TABLE measurement_y2006m02;

# 将分区表从分区中撤出
ALTER TABLE measurement_y2006m02 NO INHERIT measurement;

# 添加分区表
CREATE TABLE measurement_y2008m02 (CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' )) INHERITS (measurement);

CREATE TABLE measurement_y2008m02 (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02 CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' );\copy measurement_y2008m02 from 'measurement_y2008m02'-- possibly some other data preparation workALTER TABLE measurement_y2008m02 INHERIT measurement;


ANALYZE measurement;


猜你喜欢

转载自blog.csdn.net/chuckchen1222/article/details/80784946
今日推荐