Sql 在关系数据库中正确建模体育统计数据

Sql 在关系数据库中正确建模体育统计数据,sql,database-design,Sql,Database Design,我正在尝试用PostGreSQL对足球统计数据进行建模,我有一些有用的东西,但感觉不太对劲。问题是: 我有球队,比赛和数据。每场比赛都有两队。每支球队都有一条进攻统计线,可能包括冲刺、传球等。但是,该进攻统计暗含着另一队的防守统计,例如,如果进攻队在与防守队的比赛中冲刺100码,防守队就放弃了100码冲刺。跟踪进攻和防守数据很重要 我当前的模型将足球队、足球比赛、足球统计和足球队统计作为足球队和足球统计之间的链接表。FootballStat有一个足球游戏的外键。FootballTeamStat有

我正在尝试用PostGreSQL对足球统计数据进行建模,我有一些有用的东西,但感觉不太对劲。问题是:

我有球队,比赛和数据。每场比赛都有两队。每支球队都有一条进攻统计线,可能包括冲刺、传球等。但是,该进攻统计暗含着另一队的防守统计,例如,如果进攻队在与防守队的比赛中冲刺100码,防守队就放弃了100码冲刺。跟踪进攻和防守数据很重要

我当前的模型将足球队、足球比赛、足球统计和足球队统计作为足球队和足球统计之间的链接表。FootballStat有一个足球游戏的外键。FootballTeamStat有两个外键,一个指向FootballTeam,另一个指向FootballStat。它还有一个StatTypeId,它是进攻或防守的旗帜。通过这样做,我可以避免足球统计中的大量冗余,否则我将不得不在同一统计中有两排,但一排有进攻旗帜,另一排有防守旗帜

这在我当前的应用程序中运行得很好,但它从未感觉完全正确。有更好的方法吗?我的数据库建模经验几乎局限于我在阅读了《为凡人设计数据库》之后自己完成的项目,虽然这似乎遵循了我在那里的大部分经验,但我不确定这是否是最好的方法


编辑:更新为通用,而不是联赛专用。

你的思路是对的,我建议你把表格命名得更好一点。FootballStat和FootballTeamStat读取为包含有或没有团队上下文的统计信息。以下是我根据你的帖子所做的说明:

团队-统计-类别-代码

  • 代码
  • 描述
IE:DEF:防守型,OFF:进攻型


TEAM-STATISTICS-TYPE-CODE

  • TEAM-STATISTICS-TYPE-CODE-ID
  • 代码(FK:TEAM-STATISTICS-CATEGORY-CODE)
  • 描述
IE:1,关,冲


团队

  • 团队ID(pk)

团队统计

  • TEAM-STATISTICS-ID
  • 团队ID
  • 游戏ID
  • TEAM-STATISTICS-TYPE-CODE-ID(FK:TEAM-STATISTICS-TYPE-CODE)
  • 价值观
IE:1,1,1100

我意识到进攻和防守统计数据很重要,但是如果一个统计数据总是与进攻和防守数据相关联,那么你可以只记录进攻统计数据&使用SQL计算防守统计数据。IE:如果攻击性冲刺100码意味着防御损失100码,您是否应该从存储防御信息中获益,还是应该在数据库中创建映射,以便让SQL通过查询或查看来反转值


游戏

  • 游戏ID
  • 主队ID
  • 客场球员
  • 本垒打
  • 客场得分

您的思路是对的,我建议您对表格的命名稍微好一点。FootballStat和FootballTeamStat读取为包含有或没有团队上下文的统计信息。以下是我根据你的帖子所做的说明:

团队-统计-类别-代码

  • 代码
  • 描述
IE:DEF:防守型,OFF:进攻型


TEAM-STATISTICS-TYPE-CODE

  • TEAM-STATISTICS-TYPE-CODE-ID
  • 代码(FK:TEAM-STATISTICS-CATEGORY-CODE)
  • 描述
IE:1,关,冲


团队

  • 团队ID(pk)

团队统计

  • TEAM-STATISTICS-ID
  • 团队ID
  • 游戏ID
  • TEAM-STATISTICS-TYPE-CODE-ID(FK:TEAM-STATISTICS-TYPE-CODE)
  • 价值观
IE:1,1,1100

我意识到进攻和防守统计数据很重要,但是如果一个统计数据总是与进攻和防守数据相关联,那么你可以只记录进攻统计数据&使用SQL计算防守统计数据。IE:如果攻击性冲刺100码意味着防御损失100码,您是否应该从存储防御信息中获益,还是应该在数据库中创建映射,以便让SQL通过查询或查看来反转值


游戏

  • 游戏ID
  • 主队ID
  • 客场球员
  • 本垒打
  • 客场得分

好吧,另一种方法是摆脱足球队统计

相反,在FootballStat中添加两列:

  • 进攻队
  • 防御性事件

您还需要一个约束来保证攻击团队=防守队员,你必须在表格中扫描两次来计算一支球队的数据。但是你确实可以节省一些加入的时间。

好吧,另一种方法是去掉足球队统计

相反,在FootballStat中添加两列:

  • 进攻队
  • 防御性事件

您还需要一个约束来保证攻击团队=防守队员,你必须在表格中扫描两次来计算一支球队的数据。但是您确实可以节省一些连接。

您可以避免将统计数据存储两次。实际上,您应该避免这种情况,因为这可能会通过更新操作导致数据不一致,即使您在插入操作之前进行了所有正确的验证。您可以在teamstats和team Stats之间建立多个关系

TeamStats(stat, OffensiveTeamID, DefensiveTeamID)
示例行

Insert into TeamStats('100 yards rushing', 'Team A', 'Team B')

在这种情况下,A队的进攻是100码冲刺,B队的防守是100码防守。您需要使OffensiveTeamID和DefensiveTeamID列不为空

您可以避免将统计信息存储两次。实际上,您应该避免这种情况,因为这可能会通过更新操作导致数据不一致,即使您在插入操作之前进行了所有正确的验证。您可以在teamstats和team Stats之间建立多个关系

TeamStats(stat, OffensiveTeamID, DefensiveTeamID)
示例行

Insert into TeamStats('100 yards rushing', 'Team A', 'Team B')
在这种情况下,A队