PostgreSQLでは、パーティションテーブルのプライマリキーはパーティションキーから取得する必要があり、外部キーとして参照することはできません。 PolarDB for PostgreSQL を使用すると、パーティションテーブルの任意の列をプライマリキーとして設定し、プライマリキーを外部キーとして参照できます。
前提条件
この機能は、次のエンジンを実行するPolarDB for PostgreSQLクラスターでサポートされています。
PostgreSQL 14 (バージョン14.10.17.0以降)
次のステートメントを実行して、PolarDB for PostgreSQLクラスターのリビジョンバージョンを表示できます。
select version();
Parameters
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.)