我有这张桌子:
create table expert_country (
expert_id varchar(36) not null,
country_id varchar(36) not null,
main boolean not null default false,
primary key (expert_id, country_id),
constraint foreign key (expert_id) references expert (id),
constraint foreign key (country_id) references country (id),
-- constraint i'm looking for
);
但是我想不出我需要添加的约束,以使每个国家/地区只有一位主要专家。
我尝试了constraint unique (country_id, true)
和constraint unique (*, country_id, true)
,但是它不是有效的sql。
有什么想法吗?
答案 0 :(得分:3)
您可以使用唯一键忽略null
(遵循sql标准):任何包含null
的元组都不等同于任何元组。在唯一索引(country_id, main)
中,您可以根据需要多次设置行(1, null)
,但最多只能有一行(1, 1)
和一行(1, 0)
。
对于null
,您需要允许main
;如果是1
,则需要使用null
和0
(而非main boolean null default null,
constraint unique index uidx_expert_country (country_id, main)
)进行编码是否为专家(否则,您只能拥有一名非专家)。约束将是:
false
这可能需要更改您的应用程序,可能看起来很粗略(因为null
与null
显然不一样),并且可能使您对列的解释更加柔和(因为它现在可以包含3个值) 0
,false
/ 1
和true
/ 1
,尽管您可以通过对包含{{1 }}。
因此,如果您不想这样做,可以定义一个将在触发器中或作为生成的列计算的附加列,然后在该“虚拟”列上定义一个唯一索引:
main boolean not null default false,
main_unq boolean as (if(main = true,true, null)) stored,
constraint unique index uidx_expert_country (country_id, main_unq)
以另一种方式编码信息(哪个专家是一个国家的主要专家),您可以例如在您的main_expert_id
表中添加一列country
(并向expert_country
添加一个外键以验证该组合是否存在)并删除列main
。