当前位置: 首页 > article >正文

Redis——用户签到BitMap,UV统计

目录

BitMap

使用场景

1. 用户签到系统

2. 用户行为标记

3. 布隆过滤器(Bloom Filter)

BitMap介绍 

Redis中的使用 

Redis功能示例

添加: 

获取:

批量获取:

 java中实现

 统计本月连续签到次数

 UV统计

 UV 统计的核心需求

使用 HyperLogLog

UV 统计的常见场景

场景 1:每日 UV 统计

场景 2:月度 UV 统计


BitMap

使用场景

在开发中,Bitmap 经常被用于以下场景:

1. 用户签到系统

场景描述
用户每天签到一次,系统需要记录用户每月的签到情况,并支持快速查询连续签到天数、总签到天数等。

实现方式

  • 使用一个 Bitmap,每一位代表一天(1表示签到,0表示未签到)。

  • 例如,用户ID为1的用户在2023年10月的签到记录可以用一个31位的 Bitmap 表示。

优点

  • 存储空间极小:一个月的签到记录只需要4字节(32位)。

  • 查询效率高:可以通过位运算快速计算连续签到天数、总签到天数等。


2. 用户行为标记

场景描述
系统需要标记用户是否完成了某些行为(例如是否阅读了某篇文章、是否参与了某个活动等)。

实现方式

  • 使用一个 Bitmap,每一位代表一个行为(1表示完成,0表示未完成)。

  • 例如,用户ID为1的用户完成了行为A、B、D,可以用 0b1101 表示。

优点

  • 节省存储空间:一个用户的所有行为标记可以用一个整数表示。

  • 支持快速查询:通过位运算可以快速判断用户是否完成了某个行为。


3. 布隆过滤器(Bloom Filter)

场景描述
布隆过滤器是一种概率型数据结构,用于快速判断某个元素是否存在于一个集合中(可能存在误判,但不会漏判)。

实现方式

  • 使用一个 Bitmap 作为布隆过滤器的底层存储结构。

  • 通过多个哈希函数将元素映射到 Bitmap 的不同位置,并将这些位置标记为1。

优点

  • 空间效率极高:适合海量数据的去重和查询。

  • 查询速度快:时间复杂度为 O(1)。

BitMap介绍 

 

 如果是使用表来储存,需要耗费大量的内存,数据库压力山大

因此我们换一种方式来存储,一个月最多有31天,因此,如果某一天签到了,那么对应的位为1,没有则为0。这种方式只需要31bit,也就是8字节,大大节省了空间。

Redis中的使用 

Redis功能示例
添加: 

储存为11100111

获取:

批量获取:

u2中的u表示储存的为无符号,2表示只截取两个比特位,截取结果为11,转化为十进制就是3

 java中实现

    public Result sign() {// 获取登录用户Long userId = UserHolder.getUser().getId();// 获取日期LocalDateTime now = LocalDateTime.now();// 拼接用户和日期变成keyString keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = "sign:"+userId+keySuffix;String key = USER_SIGN_KEY+userId+keySuffix;// 获取今天是本月的第几天int dayOfMonth = now.getDayOfMonth();// 写入Redis setbit key offset 1stringRedisTemplate.opsForValue().setBit(key,dayOfMonth-1,true); // 注意这里需要减一因为在储存中字节是从0开始的return Result.ok();}

 统计本月连续签到次数

    @Overridepublic Result signCount() {// 获取登录用户Long userId = UserHolder.getUser().getId();// 获取日期LocalDateTime now = LocalDateTime.now();// 拼接用户和日期变成keyString keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = "sign:"+userId+keySuffix;String key = USER_SIGN_KEY+userId+keySuffix;// 获取今天是本月的第几天int dayOfMonth = now.getDayOfMonth();//获取本月为止的所有的签到记录,返回的是一个十进制的数字 BITFIELD key GET udayOfMonth 0List<Long> result = stringRedisTemplate.opsForValue().bitField(key,BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)) // 子命令.valueAt(0));if(result == null || result.isEmpty()){return Result.ok(0);}//  为什么需要 get(0)?get(0) 是从 List<Long> 中获取第一个元素。//  stringRedisTemplate.opsForValue().bitField(...) 返回的是一个 List<Long>,//  即使你只请求了一个值,它也会以列表的形式返回。//  因此,result.get(0) 获取的是这个列表中的第一个元素,也就是你请求的签到记录的值。Long num = result.get(0);if(num == null || num == 0){return  Result.ok(0);}// 遍历循环int cnt = 0;while(cnt < dayOfMonth){if ((num & 1) == 0) {break;}cnt++;// 把数字右移一位,抛弃最后一个bit位,继续下一个bit位num >>>=1;}return Result.ok(cnt);}

 UV统计

在 Redis 中,UV(Unique Visitor)统计 是指统计某个时间段内访问某个资源的独立用户数量。UV 统计是许多应用场景(如网站访问量统计、广告点击统计等)中的核心需求。Redis 提供了多种数据结构和方法来实现高效的 UV 统计。

以下是 Redis 中 UV 统计的相关知识点介绍:

 UV 统计的核心需求

  • 去重:同一个用户在同一时间段内的多次访问只算作一次。

  • 高效存储:需要支持海量用户的统计。

  • 快速查询:能够快速获取某个时间段内的 UV 数据。

使用 HyperLogLog

原理

  • HyperLogLog 是一种概率算法,用于估算大量数据的基数(去重后的数量)。

  • 它通过极小的存储空间(每个 HyperLogLog 键只需要 12 KB)来统计 UV。

命令

  • PFADD key user_id:将用户 ID 添加到 HyperLogLog 中。

  • PFCOUNT key:获取 UV 的估算值。

优点

  • 存储空间极小,适合海量用户的 UV 统计。

  • 查询速度快。

缺点

  • 结果是估算值,存在一定的误差(标准误差约为 0.81%)

    UV 统计的常见场景

    场景 1:每日 UV 统计

    需求

    • 统计每天的独立访问用户数。

    实现

    • 使用 HyperLogLog,每天创建一个新的键(例如 uv:2023-10-01),将当天的用户 ID 添加到键中。

    • 每天结束时,使用 PFCOUNT 获取当天的 UV 值。

    场景 2:月度 UV 统计

    需求

    • 统计每月的独立访问用户数。

    实现

    • 使用 HyperLogLog,将整个月的用户 ID 添加到同一个键中(例如 uv:2023-10)。

    • 每月结束时,使用 PFCOUNT 获取当月的 UV 值。

    相关文章:

    Redis——用户签到BitMap,UV统计

    目录 BitMap 使用场景 1. 用户签到系统 2. 用户行为标记 3. 布隆过滤器&#xff08;Bloom Filter&#xff09; BitMap介绍 Redis中的使用 Redis功能示例 添加&#xff1a; 获取&#xff1a; 批量获取&#xff1a; java中实现 统计本月连续签到次数 UV统计 UV 统计…...

    pycharm技巧--鼠标滚轮放大或缩小 Pycharm 字体大小

    1、鼠标滚轮调整字体 设置 Ctrl 鼠标滚轮调整字体大小 备注&#xff1a; 第一个是活动窗口&#xff0c;即缩放当前窗口 第二个是所有编辑器窗口&#xff0c;即缩放所有窗口的字体 2、插件 汉化包&#xff1a; Chinese Simplified 包...

    数字信任的底层逻辑:密码学核心技术与现实应用

    安全和密码学 --The Missing Semester of Your CS Education 目录 熵与密码强度密码散列函数密钥体系 3.1 对称加密 3.2 非对称加密信任模型对比典型应用案例安全实践建议扩展练习杂项 密码学是构建数字信任的基石。 本文浅析密码学在现实工具中的应用&#xff0c;涵盖 1&…...

    全面理解-深拷贝与浅拷贝

    在 C 中&#xff0c;深拷贝&#xff08;Deep Copy&#xff09; 和 浅拷贝&#xff08;Shallow Copy&#xff09; 是两种完全不同的对象拷贝策略&#xff0c;主要区别在于对指针和动态分配资源的处理方式。正确理解二者的区别是避免内存泄漏、悬空指针和程序崩溃的关键。 一、核…...

    Redis分布式锁故障处理:当Redis不可用时的应对策略

    Redis分布式锁故障处理&#xff1a;当Redis不可用时的应对策略 在分布式系统中&#xff0c;Redis因其高性能和丰富的特性常被用于实现分布式锁。但当加锁过程中Redis服务不可用时&#xff0c;系统将面临严重挑战。本文将深入探讨这一问题&#xff0c;并提供多维度解决方案。 目…...

    WordPress平台如何接入Deepseek,有效提升网站流量

    深夜改代码到崩溃&#xff1f;《2024全球CMS生态报告》揭露&#xff1a;78%的WordPress站长因API对接复杂&#xff0c;错失AI内容红利。本文实测「零代码接入Deepseek」的保姆级方案&#xff0c;配合147SEO的智能发布系统&#xff0c;让你用3个步骤实现日均50篇EEAT合规内容自动…...

    ROS ur10机械臂添加140夹爪全流程记录

    ROS ur10机械臂添加140夹爪 系统版本&#xff1a;Ubuntu20.04 Ros版本&#xff1a;noetic Moveit版本&#xff1a;moveit-noetic 参考博客&#xff1a; ur3robotiq ft sensorrobotiq 2f 140配置rviz仿真环境_有末端力传感器的仿真环境-CSDN博客 UR5机械臂仿真实例&#xf…...

    16、Python面试题解析:python中的浅拷贝和深拷贝

    在 Python 中&#xff0c;浅拷贝&#xff08;Shallow Copy&#xff09; 和 深拷贝&#xff08;Deep Copy&#xff09; 是处理对象复制的两种重要机制&#xff0c;它们的区别主要体现在对嵌套对象的处理方式上。以下是详细解析&#xff1a; 1. 浅拷贝&#xff08;Shallow Copy&a…...

    第十九天 HarmonyOS的文件操作和本地存储

    一、前言&#xff1a;为什么需要掌握文件操作与本地存储&#xff1f; 在移动应用开发中&#xff0c;文件操作和本地存储是每个开发者都必须掌握的核心技能。无论是保存用户配置、缓存网络数据&#xff0c;还是处理图片/视频等多媒体文件&#xff0c;都需要通过文件系统进行操作…...

    VLM(视觉语言模型)与DeepSeek R1(奖励机制)如何结合

    VLM&#xff08;视觉语言模型&#xff09;与DeepSeek R1&#xff08;奖励机制&#xff09;如何结合 flyfish VLM的传统训练依赖于监督学习&#xff08;直接拟合问答对&#xff09;&#xff0c;而规则奖励函数通常用于强化学习&#xff08;通过试错和奖励反馈优化策略&#xf…...

    FFMPEG编码容错处理解决办法之途径----升级库文件

    在qt开发环境下接收网络数据&#xff0c;调用ffmpeg解码播放视频&#xff0c;出现闪屏现象&#xff0c;具体现象可以使用操作系统自带的ffplay播放器播放原始视频流可复现&#xff1b;而使用操作系统自带的mpv播放器播放视频则不会出现闪屏&#xff1b;闪屏时会报Could not fin…...

    uniapp h5端和app端 使用 turn.js

    前提:添加页后,添加页与当前页会重叠在一起,不知道为什么,没有找到解决办法 1.h5端 <template><view class"container"><view id"flipbook"><view class"page page1">Page 1</view><view class"page pag…...

    【idea问题排查技巧】

    以下是针对 IDEA 中 日志打标(动态标记) 和 全链路追踪 功能的分步详解,结合具体场景和操作截图说明,帮助快速掌握实战技巧。 一、动态日志打标:不修改代码输出关键信息 1. 断点日志打印(非侵入式打标) 场景:在调试时,需要临时查看某个变量的值,但不想修改代码添加…...

    【入门音视频】音视频基础知识

    &#x1f308;前言&#x1f308; 这个系列在我学习过程中&#xff0c;对音视频知识归纳总结的笔记。因为音视频相关讲解非常稀少&#xff0c;所以我希望通过这个音视频系列&#xff0c;跟大家一起学习音视频&#xff0c;希望减少初学者在学习上的压力。同时希望也欢迎指出文章的…...

    JMeter性能问题

    性能测试中TPS上不去的几种原因 性能测试中TPS上不去的几种原因_tps一直上不去-CSDN博客 网络带宽 连接池 垃圾回收机制 压测脚本 通信连接机制 数据库配置 硬件资源 压测机 业务逻辑 系统架构 CPU过高什么原因 性能问题分析-CPU偏高 - 西瓜汁拌面 - 博客园 US C…...

    软考高级信息系统项目管理师笔记-第2章信息技术发展

    第2章 信息技术发展 2.1 信息技术及其发展 1、按表现形态的不同,信息技术可分为硬技术(物化技术)与软技术(非物化技术)。前者指各种信息设备及其功 能,如传感器、服务器、智能手机、通信卫星、笔记本电脑。后者指有关信息获取与处理的各种知识、方法 与技能,如语言文字…...

    大语言模型(LLM)提示词(Prompt)高阶撰写指南

    ——结构化思维与工程化实践 一、LLM提示词设计的核心逻辑 1. 本质认知 LLM是「超强模式识别器概率生成器」&#xff0c;提示词的本质是构建数据分布约束&#xff0c;通过语义信号引导模型激活特定知识路径。优秀提示词需实现&#xff1a; 精准性&#xff1a;消除歧义&#…...

    捷 C++ 课程学习笔记:STL 应用与复杂度分析

    一、STL 六大组件 STL&#xff08;Standard Template Library&#xff09;是 C 标准库的重要组成部分&#xff0c;提供了通用的模板类和函数&#xff0c;用于实现常用的数据结构和算法。STL 主要包括以下六大组件&#xff1a; 容器&#xff08;Containers&#xff09;&#xf…...

    【python】提取word\pdf格式内容到txt文件

    一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""读取 PDF 文件内容:param file_path: PDF 文件路径:return: 文件内容文本"""try:text ext…...

    数据结构☞泛型

    一.基础定义与应用方向 1.定义&#xff1a; 一般的类和方法&#xff0c;只能使用具体的类型 : 要么是基本类型&#xff0c;要么是自定义的类。如果要编写可以 应用于多种类型 的代码&#xff0c;这种刻板的限制对代码的束缚就会很大。----- 来源《 Java 编程思想》对泛型的介…...

    MFC学习笔记-1

    一、编辑框和按钮 //.h文件private:CString str;//给窗口类加了一个变量&#xff08;定义一个成员变量&#xff09;&#xff0c;关联到IDC_EDIT1中&#xff08;要在实现中关联&#xff0c;源文件文件夹中&#xff09;CString str2;//接收button2&#xff0c;和IDC_EDIT2绑定 p…...

    html中rel、href、src、url的区别

    1.url url&#xff08;统一资源定位符&#xff09;&#xff1a;是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示&#xff0c;是互联网上标准资源的地址。 2.href href&#xff1a;Hypertext Reference的缩写。 意思是超文本引用。 3.rel rel&#xff1a;relatio…...

    hot100-二叉树

    二叉树 二叉树递归 相当于这个的顺序来回调换 class Solution {private List<Integer> res new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root null)return res;inorderTraversal(root.left);res.add(root.val);inorde…...

    嵌入式项目:STM32刷卡指纹智能门禁系统

    本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助&#xff0c;请点链接&#xff1a; https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端&#xff08;下位机&#xff09;…...

    短剧小程序系统源码

    短剧小程序系统源码 今天我要向大家介绍的是最新作品——短剧小程序系统源码。这不仅仅是一款简单的播放工具&#xff0c;它背后蕴含的强大功能能够帮助你的短剧业务实现质的飞跃&#xff01; 为什么说这款源码很厉害&#xff1f; 首先&#xff0c;在当今竞争激烈的市场环境…...

    鸿蒙5.0实战案例:基于measure实现的文本测量

    往期推文全新看点&#xff08;文中附带全新鸿蒙5.0全栈学习笔录&#xff09; ✏️ 鸿蒙&#xff08;HarmonyOS&#xff09;北向开发知识点记录~ ✏️ 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…...

    C#中级教程(2)——走进 C# 面向对象编程:从基础到进阶的深度探索

    一、为什么选择面向对象编程 在软件开发的演进过程中&#xff0c;随着程序规模和复杂度的不断增加&#xff0c;传统的编程方式逐渐暴露出局限性。面向对象编程应运而生&#xff0c;它就像是一位智慧的组织者&#xff0c;将程序中的功能进行模块化划分。每个模块各司其职&#x…...

    基于SpringBoot的“流浪动物救助系统”的设计与实现(源码+数据库+文档+PPT)

    基于SpringBoot的“流浪动物救助系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 局部E-R图 系统首页界面 系统…...

    基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案

    随着物联网和嵌入式技术的快速发展&#xff0c;嵌入式设备对实时音视频通信的需求日益增长。然而&#xff0c;传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题&#xff0c;难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点&#xff0c;本文将介…...

    Windows - 通过ssh打开带有图形界面的程序 - 一种通过计划任务的曲折实现方式

    Windows(奇思妙想) - 通过ssh打开带有图形界面的程序 - 一种通过计划任务的曲折实现方式 前言 Windows启用OpenSSH客户端后就可以通过SSH的方式访问Windows了。但是通过SSH启动的程序&#xff1a; 无法显示图形界面会随着SSH进程的结束而结束 于是想到了一种通过执行“计划…...