mysql 约束在布尔字段为真时唯一

mysql constraint unique when boolean field is true

我有这个table:

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。 有什么想法吗?

您可以使用唯一键忽略 null(遵循 sql 标准):任何包含 null 的元组不等同于任何元组. 这意味着,在唯一索引 (country_id, main) 中,您可以根据需要多次使用行 (1, null),但最多一行 (1, 1) 和一行 (1, 0).

您需要允许 null 用于 main,并且需要使用 1null(不是 0)进行编码是不是专家(否则你只能有一个非专家)。约束将是:

main boolean null default null,
constraint unique index uidx_expert_country (country_id, main)

这可能需要更改您的应用程序,可能看起来很粗略(因为 false 显然与 null 不同)并且可能会软化您的专栏的解释(因为它现在可以包含3 个值 null0/false1/true,尽管您可以使用 table 的附加外键来防止这种情况发生单行包含 1).

因此,如果您不想这样做,您可以定义一个额外的列,该列将在触发器中计算或作为生成的列,然后在该 "dummy" 列上定义一个唯一索引:

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-table(以及 expert_country 的外键以验证组合是否存在)并删除列 main.