需求
说明
- 一般排行榜都不会做全局排名查询,因为要统计全部数据实在是太消耗性能了,一般都会做前100名,前N名
假设数据
ranks {
{user:'张一', score:'100'},
{user:'张二', score:'90'},
{user:'张三', score:'80'},
{user:'张四', score:'70'},
{user:'张五', score:'60'},
{user:'张六', score:'500'},
{user:'张七', score:'50'},
{user:'张八', score:'50'},
}
1. 同级别排行榜,获取排名
- 这种做法在查询当前用户排名的时候非常有优势
- 只需要做 (某某)大于(70分)有(多少人)=(3名)+(1)=(第四名)
- 缺点:同一分数的排名是一样的
2. 超出排名,叫做未上榜
- 首先统计出前100名排行榜并且缓存起来
- 当获取用户排名的时候,验证用户ID是否存在排行榜中
- 如果用户ID不存在,则返回 此用户未上榜,因为太Low
3. 序号+排名,获取排名(不要求真实)
- 假设排行榜需要统计超过100名的用户的排名
- 首先判断用户是否存在 前100 如果存在则返回当前用户所处的排名
- 如果不存在 返回(用户当前注册进入序号 )+(排行榜100)+(1)=(当前排名)
- 缺点:这种做法,超出排行榜名次的用户,获取的排名都是不真实的,当然如果有虚拟销量记得加上
4. 获取完全真实的排行榜
- 这种做法能获取用户最真实的排名
- 需要专门建立一个排行榜表单,并且通过定时对排行榜的表单进行排序,保存到表中的 rank(当前排名)字段中
- 该做法能够实时获得排名最真实的排名,以及无限下拉排行榜
- 缺点:假设用户有超过100W条数据,你需要将数据查找出来再保存到排行榜中去,特别消耗性能
5. 实时性高的排行榜
- 这种做法一般是当天排行榜
- 一般采用Redis 有序集合用来实现,看计算机能承载的性能来设计排行榜的长度范围
- 具体参考:https://www.cnblogs.com/zhaoyan001/p/10782260.html
- 当然这样还是不够
- 每天12点后,还需要对当天的数据,进行持久化存储到数据库中去
- 并且对新的数据进行重新排序(更新)
6. 获取前100名排行榜
- 一般这种段排行榜,只需要通过SQL查询出来
- 然后 加上 虚拟排行榜
- 然后 合并数组 进行排序
- 最终 得出排行榜数据 进行缓存(周期:分钟)
- 这种消耗可能是最小的
7. 突然的想法,可以实现实时性的排名
- 假设排行榜的字段已经 排序好 1 - 8 名
- 用户A更新排名的时候:假如用户的分数是(100分)
- 第一步:(查询) 大于(100分)的(倒序排序用户B:一条记录)是(第几名)
- 第二步:(更新)小于(100分)的(所有用户)(Rank排名)加上(1)
- 第三步:(得到)当前(用户A)的(排名)等于(用户B)的(Rank排名)加上(1)
- 第三步:(更新)当前(用户A)的(分数)和(Rank排名)
基于这些需求
- 可以开发一个专门做排行榜的服务,并以此来开展公司
- 排行榜区分几种特性:实时性、真实性
- 排行榜区分几种类型:总榜(不保证实时性,但真实)、日榜(Redis实现,可以保证实时性,但真实)
- 然后我还真的发现了有那么一家公司:https://leancloud.cn/pricing/