我在 Postgres 15 中使用复合主键创建了分区表:
CREATE TABLE T (
id bigserial NOT NULL,
date date,
...,
PRIMARY KEY(id, date)
) PARTITION BY RANGE (test_date);
我添加了几个这样的分区:
CREATE TABLE T_2020 PARTITION OF T for values from ('2020-01-01') to ('2021-01-01');
CREATE TABLE T_2021 PARTITION OF T for values from ('2021-01-01') to ('2022-01-01');
问题:是否保证
id bigserial
列在所有分区中都是唯一的?
我从元数据中看到,为此
T
列自动创建的表 bigserial
只有 1 个序列。每个分区没有单独的序列。
这是否意味着
id
列在所有分区中都是唯一的?
问题:是否保证
列在所有分区中都是唯一的?id bigserial
答案:没有。
引用手册中章节“限制”:
要在分区表上创建唯一或主键约束, 分区键不得包含任何表达式或函数调用 并且约束的列必须包含所有分区键 列。存在此限制是因为 各个索引 构成约束只能直接强制内部的唯一性 他们自己的分区;因此,分区结构本身必须 保证不同分区不重复。
serial
列(或 bigserial
)从单个 SEQUENCE
中提取值。插入默认值时,会在整个分区表中产生唯一的 id
值。
但是,没有保证。我们可以随意手动插入重复项。就像普通(非分区)表中的
serial
列一样,不能保证唯一性。底层SEQUENCE
有助于避免独特的违规行为。只有 UNIQUE
索引(直接或间接作为 PRIMARY KEY
或 UNIQUE
约束的实现细节)实际上强制执行不同的值。 (存在 null
值的漏洞 - 但 PK 列也始终是 NOT NULL
。)
更新的
IDENTITY
专栏往往会做得更好。但仍然不能保证。参见: