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

用户刷题记录日历——签到表功能实现

MySQL实现

在数据库中设计一张签到表,记录用户每次签到的日期及其他相关信息。然后通过时间范围查询得到用户的签到记录。

CREATE TABLE user_sign_in (id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 主键,自动递增userId BIGINT NOT NULL,               -- 用户ID,关联用户表signDate DATE NOT NULL,            -- 签到日期createdTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- 记录创建时间UNIQUE KEY uq_user_date (userId, signDate)  -- 用户ID和签到日期的唯一性约束
);

通过唯一索引,可以确保同一用户在同一天内只能签到一次。v7MVXjmkYSVF6bWEkbEtbK7rqOSiRVZrvgDMFuqdQNE=

通过下面的 SQL 即可查询用户的签到记录:

SELECT signDate FROM user_sign_in 
WHERE userId = ? AND signDate BETWEENAND ?;

分析:

优点:原理简单,容易实现,适用于用户量较小的系统。

缺点:

1、存储空间占用大

字段名数据类型估算空间说明
idBIGINT8 字节主键,自增
userIdBIGINT8 字节用户ID
signDateDATE3 字节日期:YYYY-MM-DD
createdTimeTIMESTAMP4 字节时间戳(支持秒级精度)

如果存储 100 万个用户,365天的签到记录,需要 100 万× 365 × 40字节 = 14GB

随着用户量和数据量增大,对数据库的压力增大,直接查询数据库性能较差。除了单接口的响应会增加,可能整个系统都会被其拖垮。

基于缓存 Redis Set

可以利用内存缓存加速读写,常用的本地缓存是 Caffeine,分布式缓存是 Redis。

由于每个用户会有多个签到记录,很适合使用 Redis 的 Set 类型存储,每个用户对应一个键,Set 内的每个元素为签到的具体日期

Redis Key 的设计为:user:signins:{userId}

其中:

  1. user 是业务领域前缀
  2. signins 是具体操作或功能
  3. {userId} 表示每个用户,是动态值

如果 Redis 被多个项目公用,还可以在开头增加项目前缀区分,比如 interviewPal:user:signins:{userId}。

具体示例如下,可以使用 Redis 命令行工具添加值到集合中:

SADD user:signins:123 "2024-09-01"
SADD user:signins:123 "2024-09-02"

使用命令查找集合中的值:

SMEMBERS user:signins:123

优点:Set 数据结构天然支持去重,适合存储和检索打卡记录。

存储 100 万个用户 的 365 天 签到记录,使用 Redis 集合类型来存储每个用户的签到信息,每个用户需要大约 1880 字节(365 × 4字节)的空间,总共需要大约 1.88GB 的内存空间,相比数据库节约了 10 倍左右。

Bitmap 位图

Bitmap 位图,是一种使用位(bit)来表示数据的 紧凑 数据结构。每个位可以存储两个值:0 或 1,常用于表示某种状态或标志。因为每个位仅占用 1 位内存,Bitmap 在大规模存储二值数据(如布尔值)时,非常高效且节约空间。

核心思想:与其存储用户签到的具体日期,不如存储用户在今年的第 N 天是否签到

2024-01-01 => 1(第一天)
2024-01-03 => 3(第三天)

使用位图类型存储,每个用户对应一个键,Bitmap 的 每一位 来表示用户在 某一天 是否打卡。

把 int 优化成用 bit 存储,那么占用的空间可以优化 32 倍!假设原先占用的大小需要 32 G,那么改造后仅需 1 G

对于刷题签到记录场景,一个用户存储一年的数据仅需占用 46 字节,因为 46 * 8 = 368,能覆盖 365 天的记录。那一百万用户也才占用 43.8 MB,相比于 Redis Set 结构节约了 40 多倍存储空间!

Redis Key 的设计为:user:signins:{年份}:{userId}

设置某一个 bit 值的命令如下:

-- 表示用户在第 240 天打卡
SETBIT user:signins:2024:123 240 1
-- 表示用户在第 241 天打卡
SETBIT user:signins:2024:123 241 1

查询某一个 bit 值的命令:

GETBIT user:signins:2024:123 240
http://www.xdnf.cn/news/575911.html

相关文章:

  • 基于 Guns v5.1 框架的分页教程
  • SseEmitter是什么
  • 卷积神经网络基础(十)
  • chrono类 根据duration 类的周期类型得到对应的周期名称
  • 预警功能深度测评:如何用系统降低设备突发故障率?
  • JavaScript常用事件
  • 第P10周:Pytorch实现车牌识别
  • 如何解决测试覆盖率与迭代速度的冲突问题?
  • 手搓四人麻将程序
  • 正大模型视角下的高频交易因子构建策略研究
  • 视频监控管理平台EasyCVR工业与公共安全监控:监控中心与防爆系统如何集成?
  • 【免杀】C2免杀技术(八)APC注入
  • 数字化转型到底是什么?如何更好的理解数字化转型
  • NOSQL之Redis群集部署
  • 基于Browser Use + Playwright 实现AI Agent操作Web UI自动化
  • 运行时runtime是什么?(程序在运行过程中所依赖的环境、资源管理机制以及动态行为的总和)(包括内存分配、异常处理、线程调度、类型检查、资源访问等)
  • ip地址冲突说明什么问题?ip地址冲突影响网速吗
  • torch.matmul() VS torch.einsum()
  • 2025上半年软考准考证打印入口已开放!
  • ubuntu24.04+RTX5090D 显卡驱动安装
  • 支持向量存储:PostgresSQL及pgvector扩展详细安装步骤!老工程接入RAG功能必备!
  • 认知计算:迈向人类级智能的 AI 新范式
  • 关于对DDOS攻击的防御方法都有哪些?
  • EasyPan 使用及功能优化
  • 操作系统内存管理深度剖析:从虚拟内存机制到前沿技术探索
  • Spyglass:CDC官方Hands-on Training(一)
  • 什么是质量管理的核心要素?人、机、料、法、环、测解析
  • C++(26): 标准库 <queue>
  • 【原创】instagram 批量下载工具
  • 【优秀三方库研读】在 quill 开源库 Backend.h 知识点