我可以创建外键约束,从单个FK到多个PK

目前,我有 two configuration tables 存储两种不同的配置,但是,它们都有一个 ID 列 . 我有一个名为 Deactivation 的表 . 我想要停用的任何配置我可以将该配置表的 ID 添加到此表中 .

数据库的结构如下 .

我的问题是我可以创建两个引用的FK约束,

- ID (FK) to T1_ID (PK)
- ID (FK) to T2_ID (PK)

(单亲到多父母)

因此,不应允许 deactivation 表插入任何不在 T1T2 中的 id . 但如果在任何表中找到 ID 应该完成插入 .

谢谢

回答(2)

2 years ago

我认为你已经从评论中得到了答案,但这里作为直接声明:

关系数据库外键/主键机制不是为了维护和强制表之间的这种关系 . 您必须使用Deactivations上的触发器执行自定义操作,检查插入到Deactivations中的值是否存在于T1或T2中,如果不是,则允许插入/拒绝插入 .

您还需要考虑编写T1和T2中的某些内容来处理更新/删除(级联它们?)和冲突(如果 T1 id = 1T2 id = 2 ,但是然后您将T2 ID更改为1?如果ID存在,该怎么办?在T1中代表一件事,插入到代表不同的东西的T2中吗?T2中的新东西是否会自动停用?我的手机是否因为有人停止在平板电脑上支付 Contract 而停止工作?)

2 years ago

我认为你的关系是倒退的 . 基本上,您希望 deactivations (或其他一些表)拥有主键 . 然后,这可以在其他表之间共享:

create table deactivations (
     deactivationId int auto_increment primary key,
     . . .
);

create table config1 (
     config1Id int primary key,
     . . . 
     constraint fk_config1_config1Id foreign key (config1Id) references deactivations(deactivationId)
);

create table config2 (
     config2Id int primary key,
     . . . 
     constraint fk_config2_config2Id foreign key (config2Id) references deactivations(deactivationId)
);

这不是您需要的100%,因为可以在两个表之间共享 deactivationId . 有很多方法,但在MySQL中,这样的检查需要触发器 .

如果您仍想使用解决方案,可以使用生成的列:

create table deactivations (
    config1Id int,
    config2Id int,
    id int generated always as (coalesce(config1Id, config2Id)),
    constraint fk_deactivations_config1Id as foreign key (config1Id) references config1(config1Id),
    constraint fk_deactivations_config2Id as foreign key (config2Id) references config2(config2Id)
);

不幸的是,MySQL不支持检查约束,因此您需要一个触发器来保证只有一个而不是两个ID都不为空 .