问题描述
我正在使用Postgresql official documentation page on Table Partitioning来查看我的postgres版本。
我想在三列上创建表分区,并且希望通过BY LIST
方法使用声明性分区。
但是,我似乎找不到如何处理更多列的好例子,特别是BY LIST
。
在上述文档中,我仅阅读:
您可以决定在分区键中将多个列用于范围 分区(如果需要)。 (...)例如,考虑一个表范围 使用列姓氏和名字列(按此顺序)进行分区 分区键。
似乎多列的声明性分区仅适用于BY RANGE
还是不正确?
但是,如果不是这样,我发现an answer on SO告诉我如何处理BY LIST
和一栏。但就我而言,我有三列。
我的想法是做类似以下的事情(我很确定这是错误的):
CREATE TABLE my_partitioned_table (
col1 type CONSTRAINT col1_constraint CHECK (col1 = 1 or col1 = 0),col2 type CONSTRAINT col2_constraint CHECK (col2 = 'A' or col2 = 'B'),col3 type,col4 type) PARTITION BY LIST (col1,col2);
CREATE TABLE part_1a PARTITION OF my_partitioned_table
FOR VALUES IN (1,'A');
CREATE TABLE part_1b PARTITION OF my_partitioned_tabel
FOR VALUES IN (1,'B');
...
我需要一个正确的实现,因为在我的情况下,可能的分区组合很多。
解决方法
是的,不能使用具有多个分区键的列表分区。您也无法弯曲范围分区以完成所需的操作。
但是您可以使用复合类型来获取所需的内容:
CREATE TYPE part_type AS (a integer,b text);
CREATE TABLE partme (p part_type,val text) PARTITION BY LIST (p);
CREATE TABLE partme_1_B PARTITION OF partme FOR VALUES IN (ROW(1,'B'));
INSERT INTO partme VALUES (ROW(1,'B'),'x');
INSERT INTO partme VALUES (ROW(1,'C'),'x');
ERROR: no partition of relation "partme" found for row
DETAIL: Partition key of the failing row contains (p) = ((1,C)).
SELECT (p).a,(p).b,val FROM partme;
a | b | val
---+---+-----
1 | B | x
(1 row)
但是也许最好的方法是使用子分区:通过第一列对原始表进行分区,并通过第二列对分区进行分区。