排行榜设计方案总结
-
方案:运用redis的sorted set 进行实时排序。
-
Sorted set简介: 实现用到了两个数据结构: hash table和skip list。 hash table 是用redis 中的dict来实现,保证了查询效率为 O(1),而skip list 主要是保证元素实时有序,
insert和remove的操作都是 O(logn)的复杂度。 -
常用命令:
- zadd(key, socre, member) 向名称为key的zset中添加元素member, score用于排序。若已存在,则根据新score更新元素顺序。
- zrem(key, member) 删除名称为key的zset中的元素member
- zrange(key, startRank, endRank) 返回名称为key的zset(元素已按score从小到大排序) 中index从startRank到endRank之间的所有元素。
- zrevrange(key, startRank,endRank) 跟 zrange相似,只是元素是按score从大到小排序。
- zrank(key, member) 返回名称为key的zset(元素已按从小到大排序)中member元素的排名(即index,从0开始)
- zrevrank(key, member) 跟 zrank相似,只是元素是按score从大到小排序。
- zscore(key, member) 返回名称为key的zeset中元素element的score
- zrangebyscore(key, min, max) 返回名称为可以的zset中 score >= min 并且 score<= max的所有元素。
-
具体实现:
- score变更处调用 zadd()
- 取排行榜数据时,调用 zrange(key, startRank, endRank) 或者 zrevrange (key, startRank, endRank) 取决于排行榜是从小到大还是从大到小。
返回数据结构是Set其中Tuple的数据结构是:
返回元素Tuple 的总个数为: endRank - startRank +1
若出现同score的人,先到达score这个分数的人排在前面。 - 取自己的排行情况。 调用 zscore 获取自己的分数。 调用zrank(或者zrevrank)获取自己的排名。
- 取我周围的排名。更具自己的排名,算出我的上一名或者下一名的排名,再通过 zrang(key, myrank, myrank+1)或者zrang(key, myrank, myrank-1) 取数据,
注意我的排名是第一名或者最后一名的特殊情况。 - 给分数>=score的人发奖。 调用 zrangebyscore()获取所有符合条件的玩家。