对不能同时为空的多列的唯一约束
Unique constraints on multiple columns that cannot both be null
我想问一下在 Postgres 10 中是否有更好的建模以下行为的方法:
CREATE TABLE test.my_table
(
id UUID PRIMARY KEY,
id_a UUID,
id_b UUID,
some_shared_data JSONB,
UNIQUE (id_a, id_b)
);
CREATE UNIQUE INDEX IF NOT EXISTS b_null_constraint ON test.my_table (id_a) WHERE id_b IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS a_null_constraint ON test.my_table (id_b) WHERE id_a IS NULL;
ALTER TABLE test.my_table
ADD CONSTRAINT both_null_constraint CHECK (
(id_b IS NOT NULL) OR (id_a IS NOT NULL));
即约束是:
id_a
和id_b
都不能是null
id_a
和 id_b
的组合必须是唯一的(包括其中之一是 null
的情况)
感觉上面设置这个的代码表达能力不是很好。人们会以 another/more 规范化的方式这样做吗?我试着把它分成不同的表,但约束 (1.) 很难满足。
只需两个 unique
约束就可以做到这一点。第二个是:
CREATE UNIQUE INDEX IF NOT EXISTS ab_null_constraint ON my_table ( coalesce(id_a, id_b), (id_a is null) WHERE id_a IS NULL or id_b is null;
Here 是一个 db<>fiddle.
实际上,您可以将所有这些组合成一个唯一索引:
CREATE UNIQUE INDEX IF NOT EXISTS ab_null_constraint ON
my_table ( coalesce(id_a, id_b),
coalesce(id_b, id_a),
(id_a is null),
(id_b is null)
);
Here 是一个 db<>fiddle。
您可能会发现您的原始公式更易于维护。
我想问一下在 Postgres 10 中是否有更好的建模以下行为的方法:
CREATE TABLE test.my_table
(
id UUID PRIMARY KEY,
id_a UUID,
id_b UUID,
some_shared_data JSONB,
UNIQUE (id_a, id_b)
);
CREATE UNIQUE INDEX IF NOT EXISTS b_null_constraint ON test.my_table (id_a) WHERE id_b IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS a_null_constraint ON test.my_table (id_b) WHERE id_a IS NULL;
ALTER TABLE test.my_table
ADD CONSTRAINT both_null_constraint CHECK (
(id_b IS NOT NULL) OR (id_a IS NOT NULL));
即约束是:
id_a
和id_b
都不能是null
id_a
和id_b
的组合必须是唯一的(包括其中之一是null
的情况)
感觉上面设置这个的代码表达能力不是很好。人们会以 another/more 规范化的方式这样做吗?我试着把它分成不同的表,但约束 (1.) 很难满足。
只需两个 unique
约束就可以做到这一点。第二个是:
CREATE UNIQUE INDEX IF NOT EXISTS ab_null_constraint ON my_table ( coalesce(id_a, id_b), (id_a is null) WHERE id_a IS NULL or id_b is null;
Here 是一个 db<>fiddle.
实际上,您可以将所有这些组合成一个唯一索引:
CREATE UNIQUE INDEX IF NOT EXISTS ab_null_constraint ON
my_table ( coalesce(id_a, id_b),
coalesce(id_b, id_a),
(id_a is null),
(id_b is null)
);
Here 是一个 db<>fiddle。
您可能会发现您的原始公式更易于维护。