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
,并且需要使用 1
和 null
(不是 0
)进行编码是不是专家(否则你只能有一个非专家)。约束将是:
main boolean null default null,
constraint unique index uidx_expert_country (country_id, main)
这可能需要更改您的应用程序,可能看起来很粗略(因为 false
显然与 null
不同)并且可能会软化您的专栏的解释(因为它现在可以包含3 个值 null
、0
/false
和 1
/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
.
我有这个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
,并且需要使用 1
和 null
(不是 0
)进行编码是不是专家(否则你只能有一个非专家)。约束将是:
main boolean null default null,
constraint unique index uidx_expert_country (country_id, main)
这可能需要更改您的应用程序,可能看起来很粗略(因为 false
显然与 null
不同)并且可能会软化您的专栏的解释(因为它现在可以包含3 个值 null
、0
/false
和 1
/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
.