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 进行分区,按第二列进行分区。
我正在查看我的 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 进行分区,按第二列进行分区。