Redis BitMap 实现签到及连续签到统计

一、引言

        用户签到功能是很多应用都离不开的一个板块,单词打开、QQ达人等等为我们所熟知,这项功能该如何实现呢,一些朋友可能想当然的觉得无非将每日的签到数据记录下来不就好了,不会去细想用谁记录,如何记录才合适。

        假如我们计入传统的关系型数据库,以MySQl为例,我们分别用INT、TINYINT、DATE分别存储用户ID、是否签到(0或1)、当天日期,那么每条记录将占用8字节(4+1+3),当用户达到一定规模,每月的签到数据存储将占用很大空间,统计查找效率也低下。

        为了解决这一问题,我们引入今天要介绍的一种Redis中的数据结构BitMap(位图)。

二、简介及基本操作

1.简介

Redis 的 Bitmap(位图)是一种基于位操作的数据结构,底层实际上是字符串(String)类型,但可以将字符串视为一个由二进制位组成的数组。每个位只能是 0 或 1,因此 Bitmap 非常适合用于存储和处理大量的布尔状态信息,而且非常节省空间。

2.基本操作

  • SETBIT:设置指定偏移量(offset)上的位的值(0 或 1)。

  • GETBIT:获取指定偏移量上的位的值。

  • BITCOUNT:计算指定范围内值为 1 的位的数量。

  • BITOP:对多个 Bitmap 进行位运算(AND、OR、XOR、NOT),并将结果存储到新的 Bitmap 中。

  • BITPOS:查找指定范围内第一个值为 0 或 1 的位的位置。

 关于位图的详细命令及RedisTemplate的详细内容大家可以自行了解。

三、签到实现

整个操作还是比较简单的,我们在收到签到请求后获取到用户信息,时间数据拼接为key对用户当月的签到操作做记录,即在位图对应位数上做写1操作(controller比较简单大家自己随手写一个测试即可)

    @Overridepublic void sign() {//获取用户Long uid = UserHolder.getUser().getId();//获取日期LocalDateTime now = LocalDateTime.now();//拼接keyString keySuffix= now.format(DateTimeFormatter.ofPattern(":yyyyMM"));String key=RedisConstants.USER_SIGN_KEY+uid+keySuffix;//本月第几天int dayOfMonth = now.getDayOfMonth();//写入redis,位图是从0开始索引的,所以减一stringRedisTemplate.opsForValue().setBit(key,dayOfMonth-1,true);}

 接下来我们用PostMan 做一下签到测试

可以看到Redis中已经存储了当前用户三月份的签到数据,也就是今天(03-31)的签到,BitMap第31位为1,代表03-31以签到,并且这一月的数据仅占4B的空间。

四、连续签到统计实现

        这里的连续签到即指当月中从当前天起往回计数,直到未签到的日子的总数,即今天没签那就算断了(如果要统计当月签到总数的话自然可以用bitCount直接统计)。

        那怎么对BitMap进行这种倒叙的计数统计呢,其实我们从其二进制的存储结构就能看出端倪,我们直接用BitMap数据和1进行与运算判断当前的最后一位是否为1,条件满足则计数并且无符号右移一位,继续对当前最后一位做判断直到不满足条件。

    public Integer signCount() {//获取用户Long uid = UserHolder.getUser().getId();//获取日期LocalDateTime now = LocalDateTime.now();//拼接keyString keySuffix= now.format(DateTimeFormatter.ofPattern(":yyyyMM"));String key=RedisConstants.USER_SIGN_KEY+uid+keySuffix;//本月第几天int dayOfMonth = now.getDayOfMonth();//截至今天的位图签到数据List<Long> result = stringRedisTemplate.opsForValue().bitField(key,BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));if (result == null||result.isEmpty()) {return 0;}Long num = result.get(0);if (num == null||num==0) {return 0;}int count=0;//循环遍历while (true){//和1做与运算,得到最后一个比特位,再和0比较if ((num & 1 ) == 0) {//为零,未签到break;}else {//为1继续计数count++;}//无符号右移1位,切换下一比特位num>>>=1;}return count;}

 我们改动一下刚刚的BitMap数据,为了方便我就不用BitField命令了,直接用工具改成如下数据

然后再用PostMan做测试,得到的连续签到天数也是4天

        本次分享主要为大家介绍一下BitMap在这种签到业务中的应用,比较简单,到这里已经全部结束,感谢大家阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端国际化-插件模式

文章目录 Webpack 插件开发解析中文调用有道翻译 API生成 JSON 语言文件React 国际化实现 Webpack 插件开发 创建 i18n-webpack-plugin.js 插件&#xff1a;在 src 目录下扫描所有文件使用 babel-parser 解析 JavaScript/JSX 代码识别中文文本通过有道翻译 API 翻译生成 local…

IP属地和发作品的地址不一样吗

在当今这个数字化时代&#xff0c;互联网已经成为人们日常生活不可或缺的一部分。随着各大社交平台功能的不断完善&#xff0c;一个新功能——IP属地显示&#xff0c;逐渐走进大众视野。这一功能在微博、抖音、快手等各大平台上得到广泛应用&#xff0c;旨在帮助公众识别虚假信…

PP-ChatOCRv3新升级:多页PDF信息抽取支持自定义提示词工程,拓展大语言模型功能边界

文本图像信息抽取技术在自动化办公、建筑工程、教育科研、金融风控、医疗健康等行业领域具有广泛应用场景。2024年9月&#xff0c;飞桨低代码开发工具PaddleX中新增文本图像智能产线PP-ChatOCRv3&#xff0c;充分结合PaddleOCR的文本图像版面解析能力和文心一言语言理解优势&am…

算法刷题记录——LeetCode篇(1.2) [第11~20题](持续更新)

更新时间&#xff1a;2025-03-29 LeetCode题解专栏&#xff1a;实战算法解题 (专栏)技术博客总目录&#xff1a;计算机技术系列目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 17. 电话号码的字母组合 给定一个仅包含数字 2-9…

如何在 vue 渲染百万行数据,vxe-table 渲染百万行数据性能对比,超大量百万级表格渲染

vxe-table 渲染百万行数据性能对比&#xff0c;超大量百万级表格渲染&#xff1b;如何在 vue 渲染百万行数据&#xff1b;当在开发项目时&#xff0c;遇到需要流畅支持百万级数据的表格时&#xff0c; vxe-table 就可以非常合适了&#xff0c;不仅支持强大的功能&#xff0c;虚…

阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)

文章目录 Github官网简介模型安装非流式应用示例流式应用示例 Github https://github.com/modelscope/FunASR 官网 https://www.funasr.com/#/ 简介 FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端…

如何使用 LLaMA-Factory 微调 LLaMA3

【LLaMa3微调】使用 LLaMA-Factory 微调LLaMA3 实验环境 1.1 机器 操作系统&#xff1a;Windows 10 或 UbuntuPyTorch 版本&#xff1a;2.1.0Python 版本&#xff1a;3.10&#xff08;针对Ubuntu 22.04&#xff09;Cuda 版本&#xff1a;12.1GPU 配置&#xff1a;p100 (16GB) …

使用Java ApI 实现Hadoop文件上传

目录 文件传输步骤 windows的本机文件传输 linux的虚拟机文件传输 文件传输步骤 建立连接 在connect2HDFS()方法中&#xff0c;通过设置Configuration对象来指定HDFS的URI&#xff08;在这个例子中为hdfs://192.168.12.133:9000&#xff09;&#xff0c;并初始化一个FileSys…

喜讯 | 耘瞳科技视觉检测与测量装备荣膺“2024机器视觉创新产品TOP10”

3月28日&#xff0c;全球机器视觉行业盛会VisionChina2025&#xff08;上海&#xff09;机器视觉展完美收官。展会期间&#xff0c;由机器视觉产业联盟&#xff08;CMVU&#xff09;举办的“2024机器视觉创新产品TOP10”企业名单正式揭晓&#xff0c;耘瞳科技“工业跨尺度场景实…

数据可视化(matplotlib)-------图表样式美化

目录 一、图表样式概述 &#xff08;一&#xff09;、默认图表样式 &#xff08;二&#xff09;、图表样式修改 1、局部修改 2、全局修改 二、使用颜色 &#xff08;一&#xff09;、使用基础颜色 1、单词缩写或单词表示的颜色 2、十六进制/HTML模式表示的颜色 3、RGB…

202518 | Ngnix

Ngnix是什么 Nginx&#xff08;发音为“engine-x”&#xff09;是一个开源的高性能HTTP服务器、反向代理服务器、负载均衡器和邮件代理服务器。它由俄罗斯程序员Igor Sysoev开发&#xff0c;首次发布于2004年&#xff0c;旨在解决C10K问题&#xff08;即如何高效地处理10,000个…

WP Mail 邮件发送:WordPress Mail SMTP设置

在我们WordPress搭建个人网站完成后&#xff0c;读者或者客户发送的电子邮件&#xff0c;包括你的WPForms电子邮件通知&#xff0c;如果无法到达预定收件人收件箱&#xff0c;这会对我们网站的运营造成很大的影响&#xff0c;问题在于WordPress Mail SMTP的发送方式。 SMTP&am…

小智机器人关键函数解析:MqttProtocol::SendAudio()对输入的音频数据进行加密处理,通过UDP发送加密后的音频数据

MqttProtocol::SendAudio()对输入的音频数据进行加密处理&#xff0c;通过UDP发送加密后的音频数据。 源码&#xff1a; void MqttProtocol::SendAudio(const std::vector<uint8_t>& data) {// 使用互斥锁保护临界区&#xff0c;确保同一时间只有一个线程可以访问该…

Hadoop 常用命令集总览

Hadoop 常用命令集总览 在大数据处理领域&#xff0c;Hadoop 作为一种广泛应用的分布式系统基础架构&#xff0c;其重要性不言而喻。熟练掌握 Hadoop 的常用命令对于高效的数据处理和分析工作至关重要。本文将对 Hadoop 的常用命令进行专业而详尽的列举&#xff0c;并结合实例进…

mac m4 Homebrew安装MySQL 8.0

1.使用Homebrew安装MySQL8 在终端中输入以下命令来安装MySQL8&#xff1a; brew install mysql8.0 安装完成后&#xff0c;您可以通过以下命令来验证MySQL是否已成功安装&#xff1a; 2.配置mysql环境变量 find / -name mysql 2>/dev/null #找到mysql的安装位置 cd /op…

GoLand 2024.3 中文 GO语言开发工具

GoLand 2024.3 中文 GO语言开发工具 文章目录 GoLand 2024.3 中文 GO语言开发工具一、介绍二、效果三、下载 一、介绍 JetBrains GoLand 2024 &#xff0c;是一款GO语言开发工具&#xff0c;全行代码补全&#xff1a;能使用本地运行的上下文感知深度学习模型&#xff0c;可以自…

Excel去掉单元格里面的换行的方法

方法一&#xff1a;使用“查找和替换”功能 ‌选中单元格‌&#xff1a;首先选中需要替换换行符的单元格或区域。 ‌打开替换窗口‌&#xff1a;按下“CtrlH”快捷键&#xff0c;打开“查找和替换”对话框。 ‌输入换行符‌&#xff1a; 在“查找内容”框中&#xff0c;你可…

React 中的 Props

Props&#xff08;Properties 的缩写&#xff09;是 React 中用于组件间通信的核心机制。它们允许数据从父组件单向传递到子组件。Props 是 React 组件不可变&#xff08;只读&#xff09;的输入参数&#xff0c;这种特性使得组件更加可预测且易于维护。 Props 的核心特性 单…

基于简单神经网络的线性回归

一、概述 本代码实现了一个简单的神经网络进行线性回归任务。通过生成包含噪声的线性数据集&#xff0c;定义一个简单的神经网络类&#xff0c;使用梯度下降算法训练网络以拟合数据&#xff0c;并最终通过可视化展示原始数据、真实线性关系以及模型的预测结果。 二、依赖库 …

‌19.思科路由器:OSPF协议引入直连路由的实验研究

思科路由器:OSPF协议引入直连路由的实验研究 一、实验拓扑二、基本配置2.1、sw1的配置2.2、开启交换机三层功能三、ospf的配置3.1、R1的配置3.2、R2的配置3.3、重启ospf进程四、引入直连路由五、验证结果随着互联网技术的不断发展,路由器作为网络互联的关键设备,其性能与稳定…