NBA比赛数据库

时间:2015-07-11 14:04:36

标签: database-design relational-database data-modeling

问题

我想知道如何为NBA比赛设计关系数据库

StackOverflow中有几个类似的问题,但没有人给出令人满意的答案。

Star Schema database for NBA/Basketball statistics

Database for Basketball teams/games/scores per season

Database Design NBA

显然游戏数据对于篮球爱好者来说很有趣,很多网站都提供这些统计数据 此外,篮球,足球等的视频游戏也应保持类似的数据。

是否有标准/推荐的方法来设计这些数据库?

实施例

我想到的解决方案如下:

团队和游戏

国家/地区 CountryCode pk,CountryName)

城市国家 pk fk, CityCode pk,CityName)

团队 TeamCode pk,TeamName,City fk)

姓名 pk,生日 pk,身高,体重,HomeTown fkCity)

就业员工 pk fkPerson, JoiningDate pk,TeamCode fk2,DepartureDate,Salary,JerseyNumber)

游戏城市 pk fk1,日期 pk,HostTeam fk2,VisitingTeam fk3)

GamePlayer 游戏 pk fk,玩家 pk fkEmployee,职位)

游戏事件

拍摄游戏 pk fk1, TimeOfGame pk,播放器fk2,ShootingType,Missed)

反弹游戏 pk fk1, TimeOfGame pk,玩家fk2,IsOffensive)

阻止游戏 pk fk1, TimeOfGame pk,Blocker fk2,Blocked fk3)

窃取游戏 pk fk1, TimeOfGame pk,Stealer fk2,Stealed fk3)

其他游戏活动......

另一种方法是仅存储每个游戏的统计数据(派生数据)。

GameStats 游戏 pk fk1,播放器 pk fk2,分钟,FieldGoal,FieldGoalMissed,ThreePointMade,ThreePointMissed,FreeThrow,FreeThrowMissed,DefensiveRebounds, OffensiveRebounds,Blocks,...)

历史数据

我遇到的这个数据模型的一个难点是玩家可以更换团队,更改球衣号码,因此我们需要存储历史数据。

游戏中的事件(射击,反弹,超时,替代等)也是历史数据。

派生数据

我遇到的另一个困难是决定是否存储派生数据。

由于派生数据导致更新异常,我们应该避免它们。但是,我发现很难完全避免派生数据。

例如

  1. 游戏统计数据是派生数据。为了避免它们,我们必须存储事件。
  2. 玩家为游戏玩的分钟来自事件(Substitution / Timeout /...)。
  3. 有些统计数据是相关的,营业额来自Steal / Block /...
  4. 对于游戏事件,游戏时间可以从一天中的时间和其他事件中获得(Substitution / Timeout /...).
  5. 为简单起见,我们应妥协并存储派生数据吗? 真正规范化的数据库是否包含派生数据?

    编辑1 - 中立体育场

    考虑到没有球队是主队的中立球场,我们可以使用以下设计。

    体育场城市 pk,名称 pk,容量)

    游戏体育馆 pk fk,日期 pk)

    TeamRole TeamRole pk)[' Home',' Away',' Neutral']

    GameTeam 游戏 pk fk,团队 pk fk, TeamRole pk fk)

1 个答案:

答案 0 :(得分:2)

如果不知道所有细节,就不可能给出完整的答案,但我可以给你一些指导,让你的生活更轻松。

在您的描述中,表格Country,City和Team似乎很好,但我不明白为什么您需要在人员表中使用City fk(除非它是出生的城市,但是列名应该清楚)。

就业

现在,关于就业表 - 我的建议有点不同:
首先,您需要决定是否只保留该表中的球员或所有与比赛相关的球队成员(例如球队教练)。
我建议第二个选项,这意味着你需要为工作类型保留另一个表格(即球员,教练,助理教练等),并在就业表中有一个fk。

历史数据

至于历史数据问题 - 您需要考虑一些规则:例如,如果您的玩家目前在团队中工作,他可能不能同时在另一个团队中工作,但是,他可以成为他的国家队的一员,同时在一支常规队伍中工作。为了解决这个问题,您必须以检查约束的形式创建一些业务逻辑规则,并且可能需要一些触发器来保持数据的完整性。
处理球队变更非常容易,因为你有球员加入球队的日期和出发日期 - 你需要的是确保常规球队中任何球员的就业之间没有重叠(记住国家队是一个例外)。

玩家在团队中工作时的变化

为了应对球衣号码的变化,或者当球员受雇于球队时可能会改变的任何数据,我建议添加一份就业详情表,该表将连接到就业表,开始日期和结束日期并保留玩家在团队中工作时可能发生的所有数据。同样,您需要确保记录与每个就业ID不重叠(日期明确)。

活跃玩家

活跃玩家表应该按照游戏计算,所以它应该将游戏ID作为fk。我建议使用gameId,teamId和playerId的简单表,而主键是gameId + PlayerId(我已经将teamId从主键中删除了,因为它是另一层保护,以防就业数据搞砸并且玩家是被认为在比赛当天在两队中都被雇用了)

<强>游戏

游戏桌应该有游戏日期+主队+客队的主键。 请注意,游戏可能会保留在中立的体育场馆,因此您需要在桌面上插入新游戏数据之前测试主队和客队的翻转游戏。此外,您可能希望保留一个体育场桌子,该桌子将有一个fk到城市并将体育场ID保留在游戏桌而不是城市id。

游戏统计

您应该努力保留一张表来描述游戏中的所有事件。 这个表当然应该有一个到游戏桌的fk和一个到团队表的fk。根据您的问题,我了解统计数据是在玩家级别完成的,因此您还希望将fk保留在玩家表中。
在游戏统计表中为统计详细信息描述和fk添加表格。基本上,它应该是这样的:

StatisticsDetails (Detail_Id,Detail_Name)
并应保存shootpassrebound等数据

在游戏统计表中,您可能需要记录涉及多个玩家的事件。有几种方法可以做到这一点,我建议尽量保持简单:在表中保留PlayerID1,PlayerId2,PlayerId3,除了第一个之外,所有这些都可以为空。

相关问题