1. 需求分析
签到一天送10 积分,签到两天送20积分,3天送30积分,4天送50积分
积分排行榜设计
2. 设计思路
2.1 数据库解决
利用关系型数据库保存积分记录,然后进行统计
积分表(t_point)
字段名 | 描述 |
---|---|
id | 主键id |
user_id | 用户id |
points | 积分 |
用户表(t_user)
id | 用户id |
---|---|
nick_name | 用户昵称 |
head_url | 头像链接 |
2.2 查询sql
使用mysql8 的 rank 进行排行
select
p.user_id userId,
sum(p.points) total,
rank () over (order by sum(p.points) desc ) rank,
u.nick_name nickName,
u.head_url headUrl
t_point p
left join t_user u on p.user_id = u.id
group by p.user_id
order by total desc limit 20
2.3 redis 解决方式
redis 命令
获取前20名 zrevrange user:points 0 19
获取前20 积分情况 zrevrange user:points 0 19 withscores
获取某一个人积分 zscore user:points 83
获取某一个人排名 : zrevrank user:points 83
2.4 coding
- redis 保存
redisTemplate.opsForZSet().incrementScore("user:points", userId, points);
- 统计积分排行
Set<ZSetOperations.TypedTuple<Integer>> rangeWithScores = redisTemplate.opsForZSet().reverseRangeWithScores("user:points", 0, 19);
- 获取排名
Long myRank = redisTemplate.opsForZSet().reverseRank("user:points", userId);
- 获取积分
Double points = redisTemplate.opsForZSet().score("user:points",userId);
3. 比较
对于数据量大的情况使用mysql无疑是雪上加霜,这个时候充分利用redis的特性, 大大的提供性能,并且mysql 没有升级没有函数rank 的话,查询性能是一个大的问题,所以这个时候使用redis无疑是最佳选择