PostgreSQL10 - 是否可以按列表进行分区(col1,col2,..,colN)?

PostgreSQL10 - is it possible to do PARTITION BY LIST (col1, col2, .., colN)?

我正在查看我的 postgres 版本的 PostgreSQL official documentation page on Table Partitioning

我想在三列上创建 table 分区,我希望使用带有 BY LIST 方法的声明性分区来做到这一点。

但是,我似乎找不到一个很好的例子来说明如何处理更多的列,特别是 BY LIST

在上述文档中我只阅读了:

You may decide to use multiple columns in the partition key for range partitioning, if desired. (...) For example, consider a table range partitioned using columns lastname and firstname (in that order) as the partition key.

多列声明式分区似乎只适用于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)

但也许最好的方法是使用子分区:按第一列对原始 table 进行分区,按第二列进行分区。