在PostgreSQL中,分區表的主鍵只能建立在分區鍵上,且不能作為外鍵引用。PolarDB PostgreSQL版支援分區表使用任意列作為主鍵或者外鍵引用。
前提條件
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(核心小版本14.10.17.0及以上)
您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:
select 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.)