2016-05-17 72 views
1

我正在开发一款具有多种游戏的应用程序,并且应该能够处理数百万玩家。每个游戏都需要一个排行榜,并且必须能够显示玩家的当前位置和前10名玩家,以及玩家朋友的位置。游戏排行榜的数据库方法

目前我正在使用两个表格。

user_score

  • ID
  • USER_ID
  • game_id
  • 得分
  • created_at

用户_ MAX_SCORE

  • ID
  • USER_ID
  • game_id
  • MAX_SCORE
  • created_at
  • 的updated_at

每当用户播放首次数据的任何游戏被插入在第一和第二表。如果用户第二次玩并且得分高于他们以前的得分,我们将数据插入到user_score表中,并用新的max_score更新user_max_score表。

而为了获得用户的排名我这样开火查询。

SET @i=0; 
SELECT id, user_id, max_score, @i:[email protected]+1 AS rank 
FROM user_max_score WHERE game_id = $gameId 
ORDER BY max_score DESC, updated_at ASC; 

有没有比这更好的方法?

+0

下降了'user_max_score'表,这样做'选择USER_ID,MAX(分数)AS MAX_SCORE FROM user_score GROUP BY user_id'(见http://stackoverflow.com/questions/7745609/sql-select-仅-行与 - 最大 - 值上一列) – AmazingDreams

回答

0

我正在使用的一种方法是单表概念。所有分数都已发布,然后您可以将背景中的分数合并到汇总表中。这保持了前端的性能,并且您可以将总结信息的后台整合过程处理为累积分数的缓存表,在我使用goLang和couchbase表的情况下,但在mySql中,您会发现添加一行很多比upsert快,你会发现一条记录然后更新。由于规模和可扩展性,当前的数据库模式正在迅速转变为noSQL格式,旧式SQL模式在性能和复制方面的努力变得越来越复杂,对于单个数据库系统和小型用户群而言,您无所谓。

请求URL

HTTP POST http://[some dns]:8080/v1/post_score 

请求负载

{  
    'user_id' : '[some-user-id]', 
    'game_id' : '[some-game-id]', 
    'score' : [value], 
    'duration' : [time played], 
    'level' : [level reached], 
    'stars' : [stars gained], 
    'os'  : '[os identified]' 
} 

在数据库附加字段,由用户代理捕获。

'ip' : [detected user ip], 
'ts" : [timestamp from the server point of view]