PostgreSQL 分区表唯一索引问题

5

PostgreSQL 14

我有一些表:

CREATE TABLE sometable (
    id integer NOT NULL PRIMARY KEY UNIQUE ,
    a integer NOT NULL  DEFAULT 1,
    b varchar(32) UNIQUE)
PARTITION BY RANGE (id);

但是当我尝试执行它时,出现了以下错误:
ERROR: unique constraint on partitioned table must include all partitioning columns

如果我执行同样的表定义但没有使用PARTITION BY RANGE (id),并检查索引,我会得到以下结果:

 tablename    indexname                                   indexdef

 sometable, sometable_b_key, CREATE UNIQUE INDEX sometable_b_key ON public.sometable USING btree (b)
 sometable, sometable_pkey, CREATE UNIQUE INDEX sometable_pkey ON public.sometable USING btree (id)

那么...唯一约束存在

问题是什么?我该如何解决?

2个回答

14
在分区表上,所有主键、唯一约束和唯一索引都必须包含分区表达式。因为对分区表的索引是通过每个分区上的单独索引实现的,没有办法在不同的索引之间强制执行唯一性。
如果想使用分区,就必须牺牲一些一致性保证。这是无法避免的。你可以在分区上创建唯一约束,这将保证每个分区内的唯一性,但不保证全局唯一性。

谢谢!但是有没有办法限制列B中的重复项? - vantaqada
1
没有。 - Laurenz Albe

2
这个限制也在文档中提到了。
引用: 5.11.2.3. 限制 下面是分区表的限制: 唯一约束(因此主键)必须包括所有分区键列。存在这种限制是因为构成约束的各个索引只能直接在其自己的分区内强制执行唯一性;因此,分区结构本身必须保证不同分区中没有重复。 无法创建跨越整个分区表的排除约束。只能在每个叶子分区上放置这样的约束。同样,这种限制源于无法强制执行跨分区限制。

https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接