我想做一些类似的事情:
create table foo (
foo_id int,
cutlery text,
primary key (foo_id, cutlery)
unique (foo_id)
) partition by list (cutlery);
create table foo_spoon partition of foo for values in ('SPOON');
create table foo_fork partition of foo for values in ('FORK');
但 postgres 提示:
[0A000] ERROR: insufficient columns in UNIQUE constraint definition
Detail: UNIQUE constraint on table "foo" lacks column "cutlery" which is part of the partition key.
我可以为每个分区表在 foo_id 上添加一个唯一约束,但它不会阻止执行类似的操作
insert into foo_spoon (foo_id, cutlery) values (1, 'SPOON'); -- this goes into one partition insert into foo_fork (foo_id, cutlery) values (1, 'FORK'); -- this goes into another partition
有没有解决这个问题的好方法,是唯一基于触发器的解决方案吗?
使用触发器我做了类似的事情:
create or replace function _check_duplicate_foo_id() returns trigger as $$ begin if exists (select count(*) from foo where foo.foo_id = new.foo_id having count(*) <> 1) then raise exception 'Duplicate foo.foo_id %s', new.foo_id; end if; return new; end; $$ language plpgsql; create trigger _check_duplicate_foo_id_trig after insert or update on foo_spoon for each row execute procedure _check_duplicate_foo_id(); -- same for foo_fork
这是正确的方向还是看起来完全疯狂?
最佳答案
由于 Postgres 中如何实现独特的约束,没有内置的“好”方法来处理这个问题。 docs note this limitation :
Unique constraints on partitioned tables must include all the partition key columns. This limitation exists because PostgreSQL can only enforce uniqueness in each partition individually.
唯一约束是使用索引实现的,每个索引仅适用于单个分区,因此在多个分区之间强制执行唯一性必须使用某种其他机制。
关于postgresql - 如何在 postgres 12 中对分区表的复合主键的列部分添加或模拟唯一性约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60178791/