我正在尝试简化数据库结构,并且我有两个表 matches
和 team_statistics
:
Here in the team_statistics
table the team_statistics.team_id
should be a foreign key that references matches.teams_id
and matches.teams_id1
and similarly team_statistics.group_id
应该是引用 matches.groups_id
和 matches.groups_id1
的外键
如何在 PostgreSQL 中做到这一点?
如果有其他方法可以通过在 matches
和 team_statistics
之间设置另一个表来做到这一点,我愿意接受建议,但我仍然想知道如何让一个外键引用两个主键。
原文由 pinch boi triggered af 发布,翻译遵循 CC BY-SA 4.0 许可协议
FK 约束规则
要回答标题和文本末尾的问题:
“我仍然想知道如何让一个外键引用两个主键。”
这不可能。
一个
FOREIGN KEY
约束只能指向 一个 表,每个表只能有 一个PRIMARY KEY
约束。或者,您可以在同一列上拥有 多个
FOREIGN KEY
约束,每个都引用 _一个_(不同)表中的一个PRIMARY KEY
。 (很少有用。)但是,单个 PK 或 FK 可以 跨越多个列。
FK 可以引用目标中任何明确定义的唯一(组)列,而不仅仅是 PK。 手册:
多列 PK 或
UNIQUE
约束只能由具有匹配列类型的多列 FK 约束引用。你问什么
由于不允许在
UNIQUE
或PRIMARY KEY
约束的列列表中多次使用同一列,因此FOREIGN KEY
的目标列表也可以不要多次使用同一列。但是没有什么可以阻止我们在 源 列表中多次使用同一列。这就是实现您所要求的内容的潜力(但可能并非有意):“在
team_statistics
表中team_statistics.team_id
应该是一个外键引用matches.team_id
和matches.team_id1
”需要定义
matches
表中的组合(team_id, team_id1)
UNIQUE
。team_statistics.team_id
中的值将仅限于表team = team1
中的matches
作为逻辑结果:甚至可能对某些设置有意义,但不是你的。
你可能需要什么
我有根据的猜测是你想要这样的东西:
(match_id, team_id)
in tableteam_statistics
should be a foreign key that references either(match_id, team_id)
or(match_id, team_id1)
in tablematches
.这对于 FK 约束和只有两个表是不可能的。您 可以 使用假的
IMMUTABLE
函数滥用CHECK
约束并使其成为NOT VALID
。请参阅此答案中的“使用 CHECK 约束更便宜”一章:但这是高级诡计,不太可靠。这里不是我的建议,所以我不打算详细说明。我建议以一种有用的方式 _规范_ 您的架构,例如:
home
标志着比赛的主队,但通过包含在 PK 中,也限制 _每场比赛最多两支球队_。 (PK 列被隐式定义为NOT NULL
。)可选的
UNIQUE
约束(team_id, match_id)
防止球队与自己比赛。通过使用索引列的倒序(与执行规则无关),这也提供了与 PK 互补的索引,这通常也很有用。看:您 可以 添加一个单独的
match_team_statistics
,但这只是match_team
现在的可选 1:1 扩展。或者,只需将列添加到match_team
。我可能会为典型显示添加 视图,例如:
基本建议: