@这是小豪的第十一篇文章

上篇文章 已经对 Redis 基础命令进行了一个大致的学习,接下来我们就需要解决 Issue “增加用户活跃度统计” 啦!

其实当我看到这个 Issue 的时候,我的第一反应是利用 MySql 来实现,创建一个签到表,记录用户 ID 和 签到时间,然后统计的时候从数据库中取出来然后聚合计算,完美,哈哈。

但是当看到要求说要用 Redis 位运算的时候,我就在想,为啥呢,仔细想了一哈,发现如果用 MySql 来实现的话虽然简单粗暴,但是也有弊端,比如我们想要做一些复杂的功能就不是太方便了,或者说不是太高性能了,比如,今天是连续签到的第几天,在一定时间内连续签到了多少天。另外一方面,如果按100万用户量级来计算,一个用户每年可以产生 365条记录,100万用户的所有签到记录那就有点恐怖了,查询计算速度也会越来越慢。

所以毅然选择 Redis ,下面给大家介绍一下究竟为啥选择它。

准备

大家知道 Redis 的字符串数据都是以二进制的形式存放的,所以说 Redis 的 Bit 操作非常适合处理这个场景,因为 Bit 的值为 0 或 1,用户是否打卡也可以用 0 或 1 来表示,我们把签到的天数对应到每个字节上,打卡了就是1,没打卡就是0,那么一个用户一年下来的记录就是 365 位的长度,100万用户一年只需要耗费大约 43 M 左右的存储空间就可以了,而且速度贼快,大伙可能会问,这个究竟是怎么计算来的,我们来看一下官方的解释:

在一台 2010MacBook Pro 上,offset 为2^32-1(分配512MB)需要~300ms,offset 为2^30-1(分配128MB)需要~80ms,offset 为2^28-1(分配32 MB)需要~30ms,offset 为2^26-1(分配8MB)需要8ms。

大概的空间占用计算公式是:( offset / 8 / 1024 / 1024 )MB

这里的 offset ,大家姑且当做用户 ID 来看,哈哈。

那么究竟如何去打卡呢,我们可以利用 setbit 命令来实现,setbit 的作用说的直白点就是:在你想要的位置操作字节值,比如说用户 3 在 3月13号 签到了,那么 setbit(20190313, 3 ,1) 就可以实现签到功能了,这里的 offset 就是3,同理,不同的用户不同的日期,改变对应的值就好了。

那么下面我们来实战一下:

实例

1. 实例化一个 Redis 连接

$redis = app('redis.connection');

2. 如何去设计 key 呢?

$dayKey = 'login:'.\now()->format('Ymd'); // 输出类似:login:20190310

// 普通写法

$dayKey = 'login:'.\date('Ymd',\time());

简单粗暴,清晰明了,哈哈。

所以我们大致的格式应该是这样子的:

3. 签到

setbit - SETBIT KEY_NAME OFFSET (Time complexity: O(1))

对 key 所储存的字符串值,设置或清除指定偏移量上的位 bit

$redis->setbit($dayKey, $this->user->id, 1);

可以看到在存储方面不仅耗费内存少,快,而且操作还方便,就这么一句话就搞定了,我当初也以为会是很复杂的操作,哈哈。并且它还有非常低的灵活高效的统计计算成本。

4. 统计一周内的签到数据

bitop - BITOP operation destkey key [key ...]

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上

AND : 对一个或多个 key 求逻辑并

OR : 对一个或多个 key 求逻辑或

XOR : 对一个或多个 key 求逻辑异或

NOT : 对给定 key 求逻辑非

$redis->bitop('AND', 'threeAnd', 'login:20190311', 'login:20190312', 'login:20190313');

echo "连续三天都签到的用户数量:" . $redis->bitCount('threeAnd');

$redis->bitop('OR', 'threeOr', 'login:20190311', 'login:20190312', 'login:20190313');

echo "三天中签到用户数量(有一天签也算签了):" . $redis->bitCount('threeOr');

$redis->bitop('AND', 'monthActivities'', $redis->keys('login:201903*'));

echo "连续一个月签到用户数量:" . $redis->bitCount('monthActivities');

echo "当前用户指定天数是否签到:" . $redis->getbit('login:20190311', $this->user->id);

.....

是不是特别方便快捷的统计查询,哈哈,

结束语

从上面的例子中大家可以看到不管在存储上面还是在统计计算上面,位运算都比 mysql 的方式好太多。

至此,一个简单的签到统计功能就已经实现了,大家可以根据自己的需求扩展,不当的地方欢迎大家指正,哈哈。

本作品采用《CC 协议》,转载必须注明作者和本文链接

finecho # Lhao

php redis 签到,如何利用 Redis 快速实现签到统计功能相关推荐

  1. 利用HttpSessionListener实现网站在线人数统计功能

    为什么80%的码农都做不了架构师?>>>    在网站中经常需要进行在线人数的统计.过去的一般做法是结合登录和退出功能,即当用户输入用户名密码进行登录的时候计数器加1,然后当用户点击 ...

  2. redis服务器信息统计,利用Redis统计网站在线活跃用户的方法

    前言 在工作中我们经常遇到这样的需求,要对某个在线网站的活跃用户数量进行统计.这里我们以redis为例,说明一下其实现的过程. 实现方法 在Redis中存在bitmap这种数据类型,这种数据类型是建立 ...

  3. 利用jdt快速实现pmd的功能

    jdt可以做语法树分析,并且支持visitor模式对代码进行分析.跟pmd的分析方式一样,我们只要实现 visitor接口即可实现一个插件. @Service("requestMapping ...

  4. 利用 Xposed 快速实现一个简易微信机器人

    目标 当前微信网页版限制越来越多,考虑尝试在手机上实现类似机器人的功能.本文目的是利用 Xposed 快速实现简易机器人功能,包括获取好友发来的消息,以及回复消息.后续可以增加智能回复,比如接入图灵机 ...

  5. xposed微信长视频转发_利用 Xposed 快速实现一个简易微信机器人

    目标 当前微信网页版限制越来越多,考虑尝试在手机上实现类似机器人的功能.本文目的是利用 Xposed 快速实现简易机器人功能,包括获取好友发来的消息,以及回复消息.后续可以增加智能回复,比如接入图灵机 ...

  6. 【美文保存】nosql数据库对比以及如何巧妙利用redis来提高效率?

    1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...

  7. 利用Redis一步步实现优惠券的最终秒杀方案

    订单ID不能采用自增长的原因: 1.规律变化太明显.两天下单的ID的差值,能够计算出商城的订单量: 2.如果采用自增长,订单数据是会不断产生的,到时候要分表,但是每个表的ID都是从0开始增长的,这样I ...

  8. c#获取对象的唯一标识_在 Java 中利用 redis 实现分布式全局唯一标识服务

    作者: 杨高超 juejin.im/post/5a4984265188252b145b643e 获取全局唯一标识的方法介绍 在一个IT系统中,获取一个对象的唯一标识符是一个普遍的需求.在以前的单体应用 ...

  9. 利用redis写webshell

    redis和mongodb我之所见 最近自己在做一些个人的小创作.小项目,其中用到了mongodb和redis,最初可能对这二者没有深入的认识. 都是所谓的"非关系型数据库",有什 ...

最新文章

  1. linux下如何将mysql加入环境变量
  2. 8.15 12.13-12.16
  3. c# BindingSource的简单应用
  4. Git现实(一个)版本控制概述
  5. 做到这23条,你就成熟了!
  6. 根据表达式的值,选择field中的值
  7. ajax被token拦截,vue中封装ajax请求,并且拦截请求在请求头中添加token
  8. Re:从0开始的微服务架构:(一)重识微服务架构--转
  9. nginx添加对web status及status的每一项含义
  10. Error querying database. Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
  11. EMNLP 2020 | 基于超边融合的文本增强知识图谱开放域问答
  12. P1038 神经网络(拓扑排序)
  13. python怎么模拟浏览器交互_干货分享:python爬虫模拟浏览器的两种方法实例分析(赶紧收藏)...
  14. 安卓USB开发教程 四 安卓 AOA
  15. FBEC2021暨第六届金陀螺奖颁奖典礼盛大开幕
  16. ARMA模型的性质之ARMA模型
  17. easyUI 如何不跳转页面,只是加载替换center部分内容
  18. 史上最全的微服务知识科普
  19. phpstudy中php页面不识别php代码解决方法
  20. Easy2game使用

热门文章

  1. java代码对es操作
  2. PyCharm软件破解使用方法
  3. jersey球衣是什么_2017Jersey Zone球衣艺术博览会展品介绍(图)
  4. 转 【CDC翻客】移动端App测试实用指南
  5. 有生之年系列:《三体》动画2021年登录B站,冲击国创区最强底牌?
  6. Mybatis快速配置-不适合入门
  7. 微信小程序 错误解决方法集合(待更新)
  8. Linux IIO驱动
  9. 双排座小货车新车价格_福特双排座小卡车报价
  10. 实战Vue打包并自动部署到指定服务器