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

umb*_*987 5 postgresql partitioning postgresql-10

我正在查看关于我的 postgres 版本的表分区的 PostgreSQL 官方文档页面

我想在三列上创建表分区,并且我希望使用声明性分区和BY LIST方法来做到这一点。

但是,我似乎找不到关于如何处理更多列的好例子,特别BY LIST是。

在上述文档中我只读到:

如果需要,您可以决定在分区键中使用多列进行范围分区。(...) 例如,考虑使用列姓氏和名字(按该顺序)作为分区键对表范围进行分区。

看来多列上的声明式分区只是为了BY RANGE还是不正确?

但是,如果不是,我在 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');

...
Run Code Online (Sandbox Code Playgroud)

我需要一个正确的实现,因为在我的例子中可能的分区组合相当多。

Lau*_*lbe 6

确实如此,您不能使用具有多个分区键的列表分区。您也不能弯曲范围分区来执行您想要的操作。

但是您可以使用复合类型来获得您想要的:

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)
Run Code Online (Sandbox Code Playgroud)

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