PostgreSQL では、パーティションテーブルのプライマリキーにはパーティションキーを含める必要があり、外部キーで参照することはできません。 PolarDB for PostgreSQL はこの制限をなくします。 パーティションテーブルの任意の列をプライマリキーとして使用し、外部キーで参照できます。
適用範囲
この機能は、マイナーエンジンバージョンが 2.0.14.10.17.0 以降の PostgreSQL 14 を実行する PolarDB for PostgreSQL クラスターでサポートされています。
コンソールでマイナーエンジンバージョンを表示するか、SHOW polardb_version; 文を実行することで確認できます。 ご利用のクラスターのマイナーエンジンバージョンが要件を満たしていない場合は、マイナーエンジンバージョンをアップグレードしてください。
パラメーター
polar_pk_in_non_partition_column_mode:非パーティション列にあるプライマリキーに使用されるインデックスタイプを指定します。 有効な値は次のとおりです:
none/local_pk:非パーティション列にプライマリキーを作成することはできません。 作成しようとすると、エラーが報告されます。global_index:非パーティション列にプライマリキーを作成すると、グローバルインデックスが制約として使用されます。
制限事項
プライマリキーにすべてのパーティションキーが含まれている場合、デフォルトでローカルインデックスがプライマリキーとして使用されます。 それ以外の場合は、グローバルインデックスがプライマリキーとして使用されます。
一意性制約にすべてのパーティションキーが含まれている場合、デフォルトでローカルインデックスが一意性制約として使用されます。 それ以外の場合は、グローバルインデックスが一意性制約として使用されます。
ローカルインデックスでは制約を満たせない可能性があるため、既存のパーティションテーブルにプライマリキーを追加する場合は、グローバルインデックスを使用する必要があります。 同じルールが、一意性制約を追加する場合にも適用されます。
外部キーがその行を参照している場合、パーティションをまたがる行の更新はできません。 パーティションをまたがる更新は、削除操作の後に挿入操作を行うことと同じです。 システムが行を削除する際に、外部キーチェックが実行されます。
例
polar_pk_in_non_partition_column_mode を none に設定し、非パーティション列にプライマリキーを作成します。
SET polar_pk_in_non_partition_column_mode = none;
CREATE TABLE pt1 (a int, b int primary key, c varchar) PARTITION BY RANGE(a);
ERROR: unique constraint on partitioned table must include all partitioning columns
DETAIL: PRIMARY KEY constraint on table "pt1" lacks column "a" which is part of the partition key.polar_pk_in_non_partition_column_mode を global_index に設定し、非パーティション列にプライマリキーを作成します。
SET polar_pk_in_non_partition_column_mode = global_index;
CREATE TABLE pt1 (a int, b int primary key, c varchar) PARTITION BY RANGE(a);
CREATE TABLE pt1_p1 PARTITION OF pt1 FOR VALUES FROM (0) TO (1);
\d pt1
Partitioned table "public.pt1"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
a | integer | | |
b | integer | | not null |
c | character varying | | |
Partition key: RANGE (a)
Indexes:
"pt1_pkey" PRIMARY KEY, btree (b) GLOBAL
Number of partitions: 1 (Use \d+ to list them.)パーティションテーブルのプライマリキーにすべてのパーティションキーが含まれている場合、polar_pk_in_non_partition_column_mode の値に関係なく、ローカルインデックスがプライマリキーとして使用されます。 これは PostgreSQL のデフォルトの動作です。
CREATE TABLE pt2 (a int primary key, b int, c varchar) PARTITION BY RANGE(a);
CREATE TABLE pt2_p1 PARTITION OF pt2 FOR VALUES FROM (0) TO (1);
\d pt2
Partitioned table "public.pt2"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
a | integer | | not null |
b | integer | | |
c | character varying | | |
Partition key: RANGE (a)
Indexes:
"pt2_pkey" PRIMARY KEY, btree (a)
Number of partitions: 1 (Use \d+ to list them.)プライマリキーとしてグローバルインデックスを使用する必要がある場合は、構文を使用してテーブルのプライマリキーを変更します。
ALTER TABLE pt2 DROP CONSTRAINT pt2_pkey;
CREATE UNIQUE INDEX pt2_pkey ON pt2 (a) GLOBAL;
ALTER TABLE pt2 ADD PRIMARY KEY USING INDEX pt2_pkey;
\d pt2
Partitioned table "public.pt2"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
a | integer | | not null |
b | integer | | |
c | character varying | | |
Partition key: RANGE (a)
Indexes:
"pt2_pkey" PRIMARY KEY, btree (a) GLOBAL
Number of partitions: 1 (Use \d+ to list them.)