是否保证 bigserial 列在分区表的所有分区中是唯一的?

Is it guaranteed that bigserial column is unique across all partitions of a partitioned table?

提问人:user3440012 提问时间:7/21/2023 最后编辑:Erwin Brandstetteruser3440012 更新时间:7/21/2023 访问量:98

问:

我在 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

我从元数据中看到,只有 1 个序列为该列自动创建的表。每个分区没有单独的序列。Tbigserial

这是否意味着该列在所有分区中都是唯一的?id

PostgreSQL 设计 自增 数据库分区

评论

0赞 Bergi 7/21/2023
如果只有一个序列,我看不出怎么会不是这样
0赞 Erwin Brandstetter 7/21/2023
@Bergi:该序列有助于提供唯一的默认值,但不能保证任何内容。
0赞 Bergi 7/21/2023
@ErwinBrandstetter对。我误解了这个问题,即是否保证序列生成的值是唯一的,尽管序列是从多个分区使用的(除非有人重置序列,否则它们是唯一的),而不是问列值是否是有限制的。
0赞 Erwin Brandstetter 7/21/2023
@Bergi:是的,微妙但重要的区别。

答:

1赞 Erwin Brandstetter 7/21/2023 #1

问:是否保证该列在所有分区中都是唯一的?id bigserial

答:不可以。

引用手册中的“限制”一章:

要在分区表上创建唯一键约束或主键约束, 分区键不得包含任何表达式或函数调用 约束的列必须包含所有分区键 列。之所以存在此限制,是因为各个索引 弥补约束只能直接在内部强制执行唯一性 他们自己的分区;因此,分区结构本身必须 保证不同分区中没有重复项。

该列(或就此而言)从单个 .插入默认值时,这将导致整个分区表中出现唯一值。serialbigserialSEQUENCEid

但是不能保证。我们可以随意手动插入重复项。就像普通列(未分区)中的列一样,不能保证唯一性。底层只是有助于避免独特的违规行为。只有索引(直接或间接作为 or 约束的实现细节)才能实际强制执行不同的值。(值有漏洞 - 但 PK 列也是 。serialSEQUENCEUNIQUEPRIMARY KEYUNIQUEnullNOT NULL

请参阅此小提琴中的演示。

更新的列可以做得更好。(不过,仍然不能保证。看:IDENTITY

评论

0赞 Erwin Brandstetter 7/21/2023
@LaurenzAlbe:是的,值得一提。