数据库:哪种模式更有效?

Database: What schema is more efficient?

哪种方法最好?它们都是标准化的,但这个选项让我感到困惑。


第一种方法

这种方式空数据会少一些,但是会分的比较多。它只保存在每个 table.

中尝试,踢球或被驱逐的球员

变体一

MatchPlayer(matchId, playerId)
Try(matchId, playerId, tries)
Kick(matchId, playerId, conversions, failedConversions, dropGoals)
Card(matchId, playerId, yellow, red)

变体二

MatchPlayer(id, matchId, playerId)
Try(matchPlayerId, tries)
Kick(matchPlayerId, conversions, failedConversions, dropGoals)
Card(matchPlayerId, yellow, red)

第二种方法

这种方法会有空数据,但划分较少。它只保存 MatchStats 得分或被驱逐的球员。

变体一

MatchPlayer(matchId, playerId)
MatchStats(matchId, playerId, tries, conversions, failedConversions, dropGoals, yellow, red)

变体二

MatchPlayer(id, matchId, playerId)
MatchStats(matchPlayerId, tries, conversions, failedConversions, dropGoals, yellow, red)

第三种方法

这种方法会有更多的空数据,但分割得更少。即使玩家没有得分或被开除,它也会将所有数据保存为零。

MatchPlayer(matchId, playerId, tries, conversions, failedConversions, dropGoals, yellow, red)

第四种方法

这种方法完全不会有空数据,但会分得更多。

变体一

MatchPlayer(matchId, playerId)
Try(matchId, playerId, tries)
Conversion(matchId, playerId, conversions)
FailedConversion(matchId, playerId, failedConversions)
DropGoal(matchId, playerId, dropGoals)
YellowCard(matchId, playerId, yellow)
RedCard(matchId, playerId, red)

变体二

MatchPlayer(matchPlayerId, matchId, playerId)
Try(matchPlayerId, tries)
Conversion(matchPlayerId, conversions)
FailedConversion(matchPlayerId, failedConversions)
DropGoal(matchPlayerId, dropGoals)
YellowCard(matchPlayerId, yellow)
RedCard(matchPlayerId, red)

你怎么看?

我会选择第二种方法,变体 1。如果您只在每场比赛后添加每个球员的数据,然后稍后查询,将所有数据放在一个 table 中将使大多数查询更简单(以及整体数据库结构)。

虽然其他方法可能更好 design-wise,但 multi-table 连接会很烦人。

但是,我会为比赛中的每个球员都包含一行(尝试次数为 0 等)。这将确保您在编制统计信息时不必将它们视为特例。当然,这将取决于实际查询以及您如何编写它们,因此请考虑将其作为一个选项。

请注意,此建议基于直觉,并且您对实际应用的了解有限。

第三种方法似乎很合理 - 它是一种关系 table,其属性描述了这种关系。您有关系的复合键,只要关系存在,您的属性就有预期值。

在效率方面,你的table并不是特别宽,所以扫描table来计算聚合统计的效率并没有受到影响。对于以下查询,所有方法都具有相似的性能:

  • 列出一场比赛中所有球员的统计数据
  • 列出球员比赛的统计数据

这些查询在每种情况下都将依赖于 关系 table 的索引,并查找连接的 table。考虑到您可能期望每场比赛或每个球员的结果中的行数,连接并不重要。但是,如前所述,第三种方法消除了对任何连接的需要,同时保持了适当的规范化水平。