sql - “多个”外键
问题描述
我有桌子:
- 音乐家 (musician_id, ...)
- 程序 (programmer_id, ...)
- COPS (cop_id, ...)
然后我将有一个特定的表
- RICH_PEOPLE (rich_person_id, ...)
哪里rich_person_id
是musician_id
,programmer_id
或cop_id
。(假设所有的musician_id
s, programmer_id
s, cop_id
s 都是不同的。)
是否可以直接在现场创建外键rich_person_id
?
PS我希望数据库
- 在将新记录插入之前,确保有一个记录
MUSICIANS
,PROGRAMMERS
或者COPS
与新记录具有相同的 idRICH_PEOPLE
rich_person_id
RICH_PEOPLE
- 如果存在具有相同 id 的记录,则从其中删除
MUSICIANS
,PROGRAMMERS
或者COPS
将失败(或需要级联删除)RICH_PEOPLE
PPS 我不喜欢
- 创建一个额外的表,如
POSSIBLY_RICH_PEOPLE
唯一的字段possibly_rich_person_id
- 创建触发器
解决方案
您可以创建三个可为空的外键,每个外表一个。然后使用CHECK
约束确保在任何给定时间只有一个值不为空。
例如:
create table rich_people (
rich_person_id int primary key not null,
musician_id int references musicians (musician_id),
programmer_id int references programmers (programmer_id),
cop_id int references cops (cop_id),
check (musician_id is not null and programmer_id is null and cop_id is null
or musician_id is null and programmer_id is not null and cop_id is null
or musician_id is null and programmer_id is null and cop_id is not null)
);
这样,将始终确保参照完整性。删除将需要级联删除或其他策略来保持数据完整性。
推荐阅读
- matlab - 读取具有已知数据类型序列的二进制文件
- sql-server - 具有定义起点的递归 SQL 查询
- firebase - 如何在不覆盖孩子的情况下更新?
- javascript - 如何在 Node 中获取 ES 模块父级?
- java - SAP PI UDF 将没有时间的日期转换为日期时间 ISO8601 字符串
- firebase - 如何在颤动中取消firebase异步请求而不是检查已安装
- android - 以编程方式打开 Android 通知
- android-studio - Android Studio 坚持解决 Flutter 中的依赖关系
- ios - Objective-C 找不到导入的 WKWebView 的实例方法
- typescript - 如何使用其接口初始化对象?