如何解决如何在 MySQL 的约束中检查外键引用的记录的值
我目前在 arch 上使用 MariaDB,在 “生产” 中使用 debian buster 代表作为 mysql。
我正在尝试创建以下架构:
create or replace schema `test`
use `test`;
create table `tags`
(
`tag_id` int not null auto_increment,`tag_display_name` varchar(200) not null unique,`tag_meta` boolean not null,primary key (`tag_id`)
);
create table `tag_aliases`
(
`alias_id` int not null,`tag_id` int not null,primary key (`alias_id`,`tag_id`),foreign key (`alias_id`) references `tags` (`tag_id`),foreign key (`tag_id`) references `tags` (`tag_id`),-- This constraint I am trying to make that doesn't work (some kind of syntax error 1064)
CONSTRAINT `cnstrnt` check (select `tag_meta` from `tags` where `tag_id`=`alias_id` limit 1)
);
目标是与具有 tags
列为 true 的 tag_meta
以及任何其他 tags
(元与否)建立 m:n 关系。
但是我找不到任何关于此的资源,因为每次我尝试使用谷歌搜索时,我都会看到到处都是外键约束。
我也尝试创建一个函数,但它说该函数不能在 check 子句中使用。 (错误 1901)
-- The function
DELIMITER //
create or replace function tagIsMeta(id int) returns boolean
begin
declare res boolean default null;
select `tag_meta` into res from `tags` where `tag_id` = id limit 1;
return res;
end //
DELIMITER ;
-- The constraint
create table ....
(
...
...
CONSTRAINT `cnstrnt` check (tagIsMeta(`alias_id`))
);
解决方法
这是一个解决方案:
create table `tags` (
`tag_id` int not null auto_increment,`tag_display_name` varchar(200) not null unique,`tag_meta` boolean not null,primary key (`tag_id`),key (`tag_id`,`tag_meta`)
);
create table `tag_aliases` (
`alias_id` int not null,`tag_id` int not null,`tag_meta` boolean not null default true,primary key (`alias_id`),foreign key (`alias_id`) references `tags` (`tag_id`),foreign key (`tag_id`,`tag_meta`) references `tags` (`tag_id`,`tag_meta`),check (`tag_meta` = true)
);
这使用了 InnoDB 的一个非标准特性,它允许外键引用父表的非唯一索引。通常这是要避免的,因为子行引用多个父行意味着什么?但在本例中,由于 tags.tag_id
本身是唯一的,因此不会发生这种情况。
其工作方式是 tag_aliases
中的列对必须与 tags
中的相应列匹配。但是我们在 tag_aliases.tag_meta
上设置了一个检查约束,它必须是 true,因此只有当它引用 tags
中具有 {{1} }.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。