我在当前的架构中看到两个问题,一个是必须检查表中的两个字段以确定复合键是否有效地重复的问题,并且一些汇总数据汇总到各个表中以进行单独处理实体(尤其是获胜者,但也可能是玩家的等级)。
对于第一个问题,没有数据库中的技巧可以使复合键的任何一个/任何字段都以您要查找的OR方式进行处理,但是如果您的数据库支持,则可以创建一个函数getPlayerTeams(player_id)
来封装查询。
(您还可以创建一个视图,其中team_thumbprint计算为已排序玩家ID的哈希值,因此,相同两个人的任何组合都始终产生相同的指纹,但这在这里可能要花很多钱)。
就标准化而言,请考虑通过使用team_result
表跟踪给定团队的所有结果来将实体与发生的结果分离。更极端的归一化也需要一张player_rating_hist
表格,其中包含玩家的所有评分更改。他们当前的评分只是最新日期。玩家视图也可以用于包含最新值,以便于查询。
拟议的架构(对不起,没有图表):
player
id
name
created_on
updated_on
player_rating_hist
player_id (FK)
rating
rating_date
team
id
player1_id (FK)
player2_id (FK)
created_on
updated_on
game
id
team1_id (FK)
team2_id (FK)
team_game
team_id (FK)
game_id (FK)
result
score
rating_change
team_rating_hist
team_id (FK)
rating
rating_date
查询:
--Results for the game, should only ever be two rows for any given game
SELECT * FROM team_game WHERE game_id = 101
--All results for a team
SELECT * FROM team_game WHERE team_id = 123456
这种结构允许将“基本”实体(玩家和团队)与由于系统随着时间的流逝而出现的“内容”分开,这意味着您不会用当前等级不断更新其中一个基本表,这些是派生值,应该通过获取最新评级,平均评级,COUNT
赢或输等来检索。如果系统足够大,则可以考虑将此类汇总数据提取到单独的“仓库”中(即使它只是同一数据库中一组单独的表)也可以简化分析。