3

如果我有一个match table ( id , details)andteam table (id,name) 并且我想让给定的两支球队进行所有比赛。

我的解决方案是:

创建第三个表包含在(match_id,team1_id,team2_id)

这是这种情况下的最佳做法吗?

4

2 回答 2

2

您不需要第三张表 - 直接从match表中引用团队:

在此处输入图像描述

只是为了澄清,{team1_id, team2_id}应该是一个关键,让同一对球队参与不止一场比赛。当然,不用说您需要适当的 FK 和.CHECK(team1_id <> team2_id)

要获得给定球队的比赛,你需要..

SELECT ... WHERE team1_id = :given_team_id OR team2_id = :given_team_id

...因此您需要两个团队 ID 的索引,如上I1I2所示。

此外,出于性能原因考虑使这些索引更宽。例如,如果您只获取有限的字段子集......

SELECT team1_id, team2_id FROM ...

...并扩大索引以覆盖这些字段(I1: {team1_id, team2_id}I2: {team2_id, team1_id}),DBMS 根本不必触及您的表堆来满足查询。


或者,您可以考虑使用自然键,例如:

在此处输入图像描述

这将允许您消除其中一个索引(代理 PK: 下的那个{match_id}),但当然会使任何下游 FK“更胖”,这可能是也可能不是一件好事,具体取决于您要完成的工作。

根据您的查询需要,您可能会摆弄 PK 字段的顺序:

  • 例如,如果您的大多数查询都问:“给我最近 X 天的比赛”,请考虑移到match_date前面。
  • 如果您的大多数查询都要求在任何时候进行比赛,请将其放在后面。
  • 如果两者都有,那么你需要一个额外的索引。

顺便说一句,第三张桌子{match_id, team_id}适用于可以由两支以上的球队进行的比赛(例如帆船)。它还有一个不幸的特性,即只允许一个甚至零个团队 - 这是您可能需要以非声明方式防范的事情。

上面的设计确保正好有两个团队。

于 2012-10-12T11:29:44.107 回答
1

假设一场比赛只能由两个桌子进行,team1_id 和 team2_id 应该是match桌子本身的一部分作为属性。不需要单独的表。您还可以在 team1_id 和团队表的 id 之间定义 FOREIGN KEY 关系,对于 team2_id 也是如此。

可以由多个团队进行的比赛需要第三个表,在这种情况下,表结构将是 ( match_id, team_id),其中将有多个具有相同 match_id 的记录,即 match 表和 match_teams 表之间的一对多关系.

于 2012-10-12T04:30:16.267 回答