哪种数据库模型更高效

Which database model is more efficient

我正在为一款游戏设计联赛系统。
会有很多联赛,一个联赛会有50名球员。

我有两个选择:

1#

Table player{  
  playerid number primary key,
  leagueid number foreign key,
  score number
}

Table league{   
  leageuid number primary key  
}

每当有 leagueid "x" 的玩家想要获得当前排行榜时。

  1. 后端将 select 所有具有 leagueid "x" 的玩家
  2. 使用玩家的当前得分和 return.
  3. 对数据进行排序

2#

 Table player{  
      playerid number primary key,
      leagueuid number foreign key,
      score number
    }

 Table league{   
      leagueid number primary key
      playersList array of playerid's
    }

每当有 leagueid "x" 的玩家想要获得当前排行榜时。

  1. 后端将 select leagueid 为“x”的联盟
  2. 对于“playerList”中的每个playerid,从“player”中获取“playerid”的当前分数table。
  3. 对所有分数进行排序,然后return

哪个选项更好?如果有更有效的方法,请告诉我。

如果您使用解决方案 #2,您在 league.playersList 中有冗余信息。

如果有一天你发现两个联赛的名单中有同一名球员,你该怎么办?您如何确定其中哪一个是正确的?

如果您随后检查 player table 中的同一名球员,发现它引用了第三个联赛,而该联赛甚至没有在 [=12] 中列出该球员,该怎么办? =]?现在,您如何确定 任何 数据都是准确的?您必须对每个联赛的 playersList 进行完整搜索,并将其与该球员记录中的 leagueid 进行比较。

这是怎么发生的?它会再次发生吗?你怎么知道它是否再次发生?您是否需要每天根据各自的玩家记录重新验证所有玩家列表?

这显示了当您将值存储在数据库的“列表”中时遇到的问题。您最终会得到非规范化的数据,这会产生许多您需要注意并不可避免地需要修复的潜在错误情况。

使用解决方案#1。在 player.leagueid 上添加索引以提高搜索效率。


回复您的评论:

Performance issue ... Selecting the players with the same "leagueid" and sorting them every time a user views the leaderboard?

这就是索引对您有很大帮助的地方。索引的目的是让您搜索 leagueid 以找到匹配的行,而不必读取所有 100 万行。

(leagueid, score) 上的复合索引通过避免排序会更有帮助。通过确保索引 returns 行按照您想要排序的顺序排列,排序就变成了空操作。

你可能会喜欢我的介绍How to Design Indexes, Really, or the video of me presenting it


P.S。有关在列表中存储值的更多问题,请参阅我对 Is storing a delimited list in a database column really that bad? 的回答。