Redis实现用户签到

news2024/11/15 21:57:34

用户签到

现在许多的APP或者网上应用为了提高用户的活跃度,都会设置一个每日签到的活动,签到完成后会给予一定的奖励,从而达到其目的。

而记录用户的签到信息可以使用如下一张数据库表来进行记录。

image-20230529151452091

在用户数量并不多的情况下,数据库勉强能支撑的住。然而当用户量达到上千万级别,假设每天每年平均签到次数才10次,然而这张表一年的数据量却已经达到上亿条。这样的数量级已经很恐怖了,但现实数据往往不止这么点。这个时候,使用数据库来存储签到信息就不是一个很明智的选择了。

将这个问题抽象出来,对于一个用户来说,他的一天的签到状态无非就是已签到或者未签到这两种状态,所以完全可以用1和0二进制的形式来表示其签到状态。而其一个月的签到状态也才仅仅31个二进制位的大小。相比于数据库来存储,即省空间,对数据库也没有那么大的压力。image-20230529152404409

像这种把每一个bit位对应当月的每一天,形成的映射关系,用0和1来标示业务状态的思路称之为位图(BitMap)。

在Redis中是利用string类型数据结构实现BitMap,因此其最大上限为512M,转换为bit则为2 3 ^3 3 2 ^2 2个bit位。

Redis中关于BitMap的操作命令:

image-20230529153722477

通过help命令查询到这些命令的使用方法

image-20230529154631536

签到统计

连续签到天数:从最后一次签到开始向前统计,直到遇到第一次未签到为止,计算总的签到次数,就是连续签到天数。

获取本月到今天为止的所有签到数据

BIFIELD key GET u[dayOfMonth] 0

从后往前遍历每一个bit位的方法:

与1做与运算,就能得到最后一个bit位。随后右移一位,下一个bit位就变成了最后一个bit位。

所以实现统计用户连续签到天数的统计的业务代码如下:

public Integer signCount() {
    // 1.获取当前登录用户
    Long userId = UserHolder.getUser().getId();
    // 2.获取日期
    LocalDateTime now = LocalDateTime.now();
    // 3.拼接key
    String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
    String key = USER_SIGN_KEY + userId + keySuffix;
    // 4.获取今天是本月的第几天
    int dayOfMonth = now.getDayOfMonth();
    // 5.获取本月截止今天为止的所有的签到记录,返回的是一个十进制的数字 BITFIELD sign:5:202203 GET u14 0
    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;
    }
    // 6.循环遍历
    int count = 0;
    while (true) {
        // 6.1.让这个数字与1做与运算,得到数字的最后一个bit位  // 判断这个bit位是否为0
        if ((num & 1) == 0) {
            // 如果为0,说明未签到,结束
            break;
        }else {
            // 如果不为0,说明已签到,计数器+1
            count++;
        }
        // 把数字右移一位,抛弃最后一个bit位,继续下一个bit位
        num >>>= 1;
    }
    return count;
}

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

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

相关文章

排序算法--冒泡排序(Java语言)

冒泡排序&#xff08;Bubble Sort&#xff09;是啥&#xff1f; 冒泡排序是一种简单的排序算法。它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。走访元素…

Android:Lifecycle

整体架构 LifecycleOwner Lifecycle持有者 在ComponentActivity中new出来&#xff0c;所以Activity和Fragment自带 实现了LifecycleOwner接口的类 可以获得生命周期信息类Lifecycle Fragment和Activity都已经实现了该接口 Lifecycle Registry 生命周期注册器 可以提交生命周…

栈板识别的思考

0.啰嗦几句 最近公司又变动了&#xff0c;所以又做了一个关于视觉的项目。简单说就是栈板定位&#xff0c;主要应用在AGV叉车上&#xff0c;当然这一套流程基本适用于所有的视觉项目。主要是看算法的设计和一些人为的经验。 1.结果图 可以看到在图像上3个托盘都分割出来了&am…

青少年机器人技术一级核心知识点:机械结构及模型(三)

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…

2024考研408-计算机组成原理第七章-输入输出系统学习笔记

文章目录 前言一、IO系统基本概念1.1、输入/输出系统基本概念1.1.1、现代计算机的结构1.1.2、常见的I/O设备1.1.3、主机与I/O设备如何进行交互&#xff1f;&#xff08;认识I/O接口&#xff09;1.1.4、I/O系统的基本组成&#xff08;I/O硬件、I/O软件&#xff09;本节回顾 1.2、…

标配8155,智驾延续「高低配」,小鹏G6能否挽回颜面?

对于小鹏汽车来说&#xff0c;G6就是最后的尊严。 高工智能汽车研究院监测数据显示&#xff0c;2023年1-5月&#xff0c;小鹏汽车交付量为3.22万辆&#xff0c;同比上年同期下滑39.81%&#xff0c;是「蔚小理」三家新势力中唯一下滑的一家。 去年上市的G9&#xff08;何小鹏口中…

基于声音信号的工业设备异常检测

异常检测主要目标是将异常事件与正常事件区分开来&#xff0c;因此才有了“异常”一词。本文将介绍基于声音信号的工业机械异常检测&#xff0c;使用的数据集是MIMII声音数据集&#xff0c;该数据集很容易在网上获得。 异常检测的任务可以通过多种方式实现。其中最简单的一种方…

Hadoop基础——HDFS知识点梳理

HDFS基础知识 1. 介绍一下HDFS组成架构&#xff1f; 组成部分&#xff1a; HDFS Client,NameNode,DataNodeSecondary NameNode( HA模式下是 StandBy NameNode) Client: 客户端 文件切分&#xff0c;文件上传HDFS时&#xff0c;client将文件切分成一个一个的block&#xff0…

玩转中文AI模型攻略——ModaHub魔搭社区攻略

目录 1. 注册和登录&#xff1a; 2. 浏览和搜索&#xff1a; 3. ModaHub排行榜&#xff1a; 4. AI应用导航&#xff1a; 5. 向量数据库&#xff1a; 6. 企业Chatbot&#xff1a; ModaHub魔搭社区是一个中文AI模型开源社区&#xff0c;旨在为开发者和研究者提供一个交流、…

抓住出海中东热潮,茄子科技(海外SHAREit Group)有效助力游戏企业出海

近年来&#xff0c;随着国际形势的紧张&#xff0c;不少中国出海企业在海外市场营收受到了不同程度的影响。为摆脱这一困境&#xff0c;大家开始将目光瞄准了海外新兴市场&#xff0c;其中中东以其高速的增长&#xff0c;量利双收的回报赢得了不少中国出海企业的青睐。 与此同…

FastDDS源码剖析:源码结构分析

include: 包含Fast-DDS的头文件。这些头文件定义了库使用的公共API和数据结构。 src: 包含Fast-DDS库的源代码文件。这包括各种组件的实现&#xff0c;例如发布者、订阅者、主题和RTPS协议。 cpp: c实现Fast-DDS的主要源代码。 pcp -fastdds: Fast-DDS公共API的实现。 rtps: …

【AI】清华开源中英双语对话模型ChatGLM2-6B本地安装笔记

清华开源中英双语对话模型ChatGLM2-6B本地安装笔记 首先&#xff0c;直接上资源&#xff0c;网盘中是ChatGLM2-6B源码及模型文件&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1DciporsVT-eSiVIAeU-YmQ 提取码&#xff1a;cssa 官方的Readme已经很详尽了&#xff0…

Unreal Engine游戏引擎

Unreal Engine&#xff08;下文简称为UE&#xff09;&#xff0c;是一款由Epic Games开发的游戏引擎&#xff0c;用于创建电子游戏、虚拟现实和增强现实应用、数字孪生等内容。UE支持实时渲染、高品质的图形效果和物理模拟、可扩展的蓝图视觉脚本语言&#xff0c;以及跨平台和多…

Appium Server GUI + Appium Inspector 定位UI元素

Appium Server GUI 下载 Appium Server GUI 安装包并完成安装&#xff0c;完成安装后启动&#xff0c;点击 startServer 快速启动 Appium 服务。 Appium Inspector 下载 Appium Inspector 安装包并完成安装&#xff0c;完成安装后启动&#xff0c;填入以下内容。 Remote Hos…

蓝牙运动耳机推荐、最好用的蓝牙运动耳机排名

在现代快节奏的生活中&#xff0c;健康和锻炼成为越来越多人追求的目标。无论是户外跑步、健身房锻炼&#xff0c;还是徒步旅行&#xff0c;一个好的运动耳机是不可或缺的伴侣。它能为您提供高品质的音乐享受&#xff0c;同时保持舒适的佩戴体验&#xff0c;让您在运动中时刻保…

基于Python和MD5算法的公寓管理系统设计与实现-计算机毕设 附源码77723

基于Python和MD5算法的公寓管理系统设计与实现 摘 要 本论文主要论述了如何使用Python开发一个公寓管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述公寓管理系统的当前背景以及…

jetson nano如何读取pwm波信号?通过编码器读取车速,使用sbus串口读取,解决方案

jetson nano如何读取pwm波信号&#xff1f; 通常我们采用的是通过gpio读取&#xff0c;但是linux系统的时钟特别的不准导致计算的不对。 所以我推荐用sbus 用外围硬件&#xff0c;有pwm转sbus设备&#xff0c; 这个设备可以将pwm波转换位串口数据&#xff0c;我们只需要将输出的…

GPT上车只为人车交互?车企还在憋大招

ChatGPT改造汽车的序幕已经拉开&#xff0c;奔驰率先出手。 不久前&#xff0c;梅赛德斯-奔驰将ChatGPT集成到了车机上&#xff0c;开启了为期三个月的测试&#xff0c;结果显示&#xff0c;它的语音助手不仅可以完成简单地指令&#xff0c;还能进行连续多轮对话&#xff0c;理…

CSS 高阶小技巧 - 角向渐变的妙用!

本文将介绍一个角向渐变的一个非常有意思的小技巧&#xff01; 我们尝试使用 CSS 绘制如下图形&#xff1a; 在之前&#xff0c;类似的图案&#xff0c;其实我们有尝试过&#xff0c;在 单标签实现复杂的棋盘布局 一文中&#xff0c;我们用单标签实现了这样一个棋盘布局&#x…

从0到1:一对一交友app开发的步骤和技巧

今天与大家分享一下一对一交友app开发的步骤和技巧。 步骤 步骤一&#xff1a;确定目标用户群 在开发一对一交友app之前&#xff0c;首先需要确定目标用户群。这是非常重要的一步&#xff0c;因为只有了解目标用户的需求和偏好&#xff0c;才能更好地开发出一款满足他们需求…