文章目录

  • 一、背景
  • 二、情景再现
  • 三、 设计当天排行榜
    • redis 有序集合 sorted set用法详解
      • 1. 添加member成员和score
      • 2. 按照score的升序或降序遍历指定范围的展member 和score
      • 3. 获取指定范围的排名member
      • 4. 获取指定member的score排名
  • 四、 设计一周或每月排行榜

一、背景

   在面试中经常会遇到一些场景的问题,如果我们只会在理论上使用技术,那么学习到的理论就无法得到实践,难以掌握知识点,此文就在面试官问到如何设计排行榜一问来解析实现的过程。
   例如微信的运动排行榜,每天都有一个运动记录,可以看到排行榜,主要包含:

  1. 今天本账号下运动步数以及排名。
  2. 今天本账号列表里的好友运动步数以及排名。

二、情景再现

面试官:
如果让你设计排行榜,你要怎么实现?

我:
这个我会! 可以使用mysql, 将用户的好友列表关联的运动记录查询出来,然后通过order by 来进行排序,就可以实现了。查询自己的排行位置,只需要通过用户id来进行条件搜索就能实现。答完后,感觉信心满满!

面试官:
emm… 这种方法可以实现,mysql也确实能在业务数据量比较小的时候能够解决此问题,一旦数据量大达到千万级别的时候,不可避免地会出现慢查询,效率就会降低,有什么方法可以优化嘛?

我:
emm…,可以使用redis来实现,因为使用redis速度很快?

面试官:
嗯嗯,我们都知道redis是一种高速缓存数据库,那为啥子redis能实现?
我:

然后面试就结束了…

下面就来解释怎么使用redis来实现排行榜。

三、 设计当天排行榜

redis 有序集合 sorted set用法详解

   sorted set 是一个有序、不重复的集合, 默认升序,排序的下标从0 开始,自带一个score 值,该值可以当作排行的标准。如果 key 和score和member相等,那么在使用zadd添加的时候会出现添加不进去的情况。

1. 添加member成员和score

格式: zadd key score member

2. 按照score的升序或降序遍历指定范围的展member 和score

格式: zrange key start stop withscores or zrevrange key start stop withscores
区别: zrange按照score的 从小到大进行展示, zrevrange按照score的从大到小进行展, 两个后面都可以不用带withscores,查询出来的就不会显示score这一项。
可以使用0 -1 遍历该key下的全部score和member。

注: 如果同一个key中有两个相同的score,那么就按照他的
字典顺序来展示,如下效果:

3. 获取指定范围的排名member

格式: zrange key start stop or zrevrange key start stop
例如,我要获取到分数排名前三的member, 使用命令:

zrevrange 20210315 0 2


例如,我要获取到所有排名,使用命令:

zrevrange 20210315 0 -1

4. 获取指定member的score排名

格式: zrank key member or zrevrank key member
区别: zrank 获取到由小到大的第几个位置, zrevrank获取到的是由大到小的第几个位置。
例如我要获取上面的 zhangsan 的分数排第几,可以使用命令: zrank 20210315 zhangsan, 效果如下:

可以发现,所有的member按照score从小到大进行排序出来了,但是微信运动的步数是,步数大的在前面,因此更适合用zrevrank,另外将获取到的值进行+1 , 那么排就有了。
综合2、3和4,我们在微信好友中的运动步数score、member列表,以及member对应的排名rank 就有了!最重要的一点,把当天的日期20210315作为key就能够索引到我们想要的数据和排名了。

   面试官看你能设计出当天的排行榜,好感度逐渐增加,随后又追问了,如果要查看一周或一个月的排行榜,要怎么弄呢?

四、 设计一周或每月排行榜

  一周的数据其实就是7天数据的累加,累加完后再排序,一个月的数据原理也是一样。

  1. 计算给定一个或多个有序集的交集并将结果放到一个新的有序集合destination中。
    格式: ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
  2. 计算给定一个或多个有序集的并集并将结果放到一个新的有序集合destination中。
    格式: ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
    默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和
    下面我们造七天的数据, 可以复制到redis客户端,直接执行即可。
zadd 20210315 1000 bing
zadd 20210315 2000 zhangsan
zadd 20210315 3000 zhu
zadd 20210315 3500 zhuzhu
zadd 20210315 1500 applezadd 20210316 1000 bing
zadd 20210316 2000 zhangsan
zadd 20210316 3000 zhu
zadd 20210316 3500 zhuzhu
zadd 20210316 1500 applezadd 20210317 1000 bing
zadd 20210317 2000 zhangsan
zadd 20210317 3000 zhu
zadd 20210317 3500 zhuzhu
zadd 20210317 1500 applezadd 20210318 1000 bing
zadd 20210318 2000 zhangsan
zadd 20210318 3000 zhu
zadd 20210318 3500 zhuzhu
zadd 20210318 1500 applezadd 20210319 1000 bing
zadd 20210319 2000 zhangsan
zadd 20210319 3000 zhu
zadd 20210319 3500 zhuzhu
zadd 20210319 1500 applezadd 20210320 1000 bing
zadd 20210320 2000 zhangsan
zadd 20210320 3000 zhu
zadd 20210320 3500 zhuzhu
zadd 20210320 1500 applezadd 20210321 1000 bing
zadd 20210321 2000 zhangsan
zadd 20210321 3000 zhu
zadd 20210321 3500 zhuzhu
zadd 20210321 1500 apple

接下来,求一周的数据, 因为默认会求和,可以不用带 aggreate sum, 使用如下命令计算7天的数据:

zunionstore last_seven_days 7 20210315  20210316 20210317 20210318 20210319 20210320 20210321

结果:

可以发现,7天的数据已经累加并排序,求排行和排名就按照上述方式即可,同理一个月的数据也是这样求即可。

如何用redis设计一个运动步数排行榜?相关推荐

  1. 游戏里经常有涉及用户排行榜(金币消费排行榜),怎么设计一个良好的排行榜。

    个人记录:2018年,工作的第6到7个年头. 重点研究自己不太擅长的技术:分布式.高并发.大数据量.数据库优化.高性能.负载均衡等. 刷题是一种态度,是一种好习惯. 我刷题,我骄傲. 题目:游戏里 经 ...

  2. 面试题之如何用Java设计一个自动售货机

    如何用Java设计一个自动售货机程序是一个非常好的Java面试题.大多数情况会在面试比较senior的Java开发者的时候出现.在一个典型的代码面试中,你需要在一定的时间内根据对应的条件完成相关的代码 ...

  3. 如何用Java设计一个简单的窗口界面(学习中.1)

    如何用Java设计一个简单的窗口界面 一.前言 二.简单了解 1.Swing简介 2.框架(frame) 3.层次 三.步骤 1.打开eclipse,依次创建项目,包,类. 2.代码 2.1最简单的可 ...

  4. 为什么用redis做缓存而不是mybatis自带的缓存_如何用Java设计一个本地缓存,涨姿势了...

    最近在看Mybatis的源码,刚好看到缓存这一块,Mybatis提供了一级缓存和二级缓存:一级缓存相对来说比较简单,功能比较齐全的是二级缓存,基本上满足了一个缓存该有的功能. 当然如果拿来和专门的缓存 ...

  5. 如何用SQL设计一个图书管理系统<纯SQL>

    最近在某鱼上有小伙伴让我帮他设计一个图书管理系统的数据库,从建库到简单的数据库,现在写完了,分享给大家哦! 我们先来看看他的要求,如下图: 根据以上需求我们来编写我们的SQL语句: 1. 创建数据库用 ...

  6. 如何用Qt设计一个多文档文本编辑器

    目录 前言 一.设计目标 二.效果展示 三.设计过程 1.设计思路 1.1文件的打开和新建 1.2设置字体和字号 1.3设置字型和颜色 1.4设置文字对齐撤销等 2.核心代码 总结 前言 学习了有关Q ...

  7. python 通讯录课程设计_如何用Python设计一个通讯录类?

    直接上代码:一共三个文件 CommunicateClass.py # @File : CommunicateClass.py class Communicate(): ""&quo ...

  8. 字节面试:如何用Redis实现一个分布式锁?

    在开始提到Redis分布式锁之前,我想跟大家聊点Redis的基础知识. 说一下Redis的两个命令: SETNX key value setnx 是SET if Not eXists(如果不存在,则 ...

  9. 如何用 Netty 设计一个百万级推送服务?

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

最新文章

  1. CSS 学习-文本 段落
  2. SAP CRM WebClient UI上UI标签文本的显示逻辑
  3. 我的SharpDevelop插件之一:知识管理器(2006年博客迁移)
  4. Spring Cloud Feign 熔断器支持
  5. Android的十六进制颜色值
  6. html 去文本框中的双引号_前端·HTML基础
  7. Barefoot和Stordis在欧洲领导开源网络
  8. Java测试代码及原理
  9. mysql cast和convert函数
  10. webview适配(一):文件选择,相机拍照,相册选择
  11. 计算机为何引入16进制,计算机内存地址为什么要用16进制数来表示
  12. 【学习笔记】数理统计习题十二
  13. Eclipse:Build not configured correctly问题
  14. 前端 网络三剑客之html 02
  15. 学生管理系统IPO图_关于继续开展2019年度辅导员工作考核学生评议的通知
  16. python爬虫热点项目—滑块验证码项目(以Bilili为例)
  17. 经典《像素鸟》游戏,难道你不想自己动手开发一个嘛(附源码免费下载)
  18. python 判断是否是元音字母
  19. 一文阐述数据科学完整学习路线图
  20. python除法有余数时+1

热门文章

  1. 不用重做系统,教你如何把机械硬盘上面的系统迁移到固态硬盘!
  2. 优化工具 Neos Server
  3. 软考是什么?考哪个科目容易过?
  4. matlab 符号值转为实数,Matlab:在实现二进制到实数转换的公式时,无法获得唯一的有理数Part1...
  5. Xinlix原语OSERDESE2的使用和仿真
  6. TP房产系统_Tphouse_tpfangchan 1.2.7升级开源版多站点多城市房产系统源码带小程序
  7. 1335 工作计划的最低难度(动态规划)
  8. iso 国家名称列表
  9. 思维导图带你看遍花样百出的各类月饼?
  10. 扫码报修开启校园报修管理系统新时代