我正试图找出在PostgreSQL中跨多个可空列强制执行唯一约束的最佳方法。
考虑下表:
CREATE TABLE test_table
(
id serial NOT NULL,
col_a character varying(255),
col_b character varying(255),
col_c date,
col_d integer,
CONSTRAINT test_table_pkey PRIMARY KEY (id ),
CONSTRAINT test_table_col_a_col_b_col_c_key UNIQUE (col_a , col_b , col_c )
);
col_a
,col_b
和col_c
的组合必须是唯一的,但它们也都可以为空。
我当前强制执行唯一约束的解决方案是创建6个部分索引(下面的seudo代码):
unique(col_a, col_b) where col_c is null
unique(col_a, col_c) where col_b is null
unique(col_b, col_c) where col_a is null
unique(col_a) where col_b is null and col_c is null
unique(col_b) where col_a is null and col_c is null
unique(col_c) where col_a is null and col_b is null
这是一个'理智'的事情吗?我应该注意哪些重大的性能问题?
答案 0 :(得分:1)
据我所知,这是通过声明(使用create table
,create unique index
等)来实现这一目标的唯一方法。当然,每个索引都必须更新。如果您的桌子增长超过一定限度,这可能是一个问题。
这可能不适用于所有情况,但为了避免需要这么多索引,我将列声明为 not null ,并且我将逻辑空值在其中(例如:“清空”,“无”或“1900-01-01”)。当然,稍后,无论是在临时查询中还是在应用程序中,您都可能需要将其解码回真正的 null 。