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

基于redis的位图实现签到功能

基于Redis位图实现签到功能是一种高效且节省内存的方法。以下是分步实现的详细方案:

1. 键设计策略

采用 sign:<userId>:<YYYYMM> 格式存储每月签到数据

# 示例:用户1001在2023年8月的签到数据
sign_key = "sign:1001:202308"

2. 核心操作实现

2.1 用户签到
# 命令格式
SETBIT key offset 1

# 示例:8月3日签到(偏移量从0开始计算)
SETBIT sign:1001:202308 2 1
# Python伪代码
def sign(user_id):
    today = datetime.now()
    offset = today.day - 1  # 日期转0-based偏移量
    key = f"sign:{user_id}:{today.strftime('%Y%m')}"
    redis.setbit(key, offset, 1)
2.2 查询签到状态
# 命令格式
GETBIT key offset

# 示例:查询8月3日是否签到
GETBIT sign:1001:202308 2
def check_sign(user_id, date):
    offset = date.day - 1
    key = f"sign:{user_id}:{date.strftime('%Y%m')}"
    return redis.getbit(key, offset)
2.3 统计当月签到次数
# 命令格式
BITCOUNT key

# 示例:统计8月总签到次数
BITCOUNT sign:1001:202308
2.4 获取连续签到天数
def get_continuous_days(user_id):
    today = datetime.now()
    key = f"sign:{user_id}:{today.strftime('%Y%m')}"
    max_offset = today.day - 1
    consecutive = 0
    
    for offset in range(max_offset, -1, -1):
        if redis.getbit(key, offset):
            consecutive += 1
        else:
            break
    
    # 检查跨月情况
    if consecutive == today.day:
        last_day = today - timedelta(days=today.day)
        prev_key = f"sign:{user_id}:{last_day.strftime('%Y%m')}"
        prev_bits = redis.bitcount(prev_key)
        if prev_bits == last_day.day:
            consecutive += prev_bits
    
    return consecutive

3. 高级功能扩展

3.1 签到日历生成
def get_sign_calendar(user_id, year_month):
    key = f"sign:{user_id}:{year_month}"
    value = redis.get(key) or b'\x00'
    
    # 将二进制数据转换为位列表
    bits = bin(int.from_bytes(value, byteorder='big'))[2:]
    return [bool(int(bit)) for bit in bits.zfill(32)]  # 最多显示31天
3.2 月度统计报告
# 获取当月首次签到日期
BITPOS key 1

# 获取当月最后签到日期
BITPOS key 1 -1

4. 性能优化步骤

  1. 数据分片:对活跃用户使用多个位图分段存储
  2. 缓存策略:对频繁访问的统计结果进行短期缓存
  3. 异步处理:非实时统计任务使用后台进程处理
  4. 数据归档:定期将历史数据转存到持久化存储

5. 异常处理机制

  1. 日期有效性验证:
def validate_date(year, month, day):
    try:
        datetime(year, month, day)
        return True
    except ValueError:
        return False
  1. 偏移量范围检查:
max_day = calendar.monthrange(year, month)[1]
if offset >= max_day:
    raise InvalidOffsetError("超出当月天数范围")

6. 数据可视化示例

生成签到日历JSON:

{
  "202308": {
    "total": 18,
    "continuous": 5,
    "calendar": [
      {"day": 1, "signed": true},
      {"day": 2, "signed": false},
      ...
    ]
  }
}

7. 内存使用估算

假设:

  • 每月最大31天
  • 每个用户每月占用4字节(31位)
  • 10万活跃用户

总内存消耗:100,000用户 × 12月 × 4字节 ≈ 4.8MB

相关文章:

  • 委托者模式(掌握设计模式的核心之一)
  • 《操作系统 - 清华大学》 9 -1:进程调度:背景
  • 高频面试题(含笔试高频算法整理)基本总结回顾3
  • 零知识证明与 ZK Rollups 详解
  • 基于单片机的智能宿舍管理系统(论文+源码)
  • 如何让vllm使用modelscope而不是huggingface来下载模型?
  • C#光速入门的指南
  • XXL-JOB深度解析:新一代分布式任务调度解决方案
  • 分布式架构篇——分库分表与数据一致性保障
  • Educational Codeforces Round 175 (Rated for Div. 2)
  • KTV点歌系统
  • Windows逆向工程入门之MASM浮点数存储机制
  • 小米 SU7 Ultra:科技与性能的极致融合,FPC 隐匿的关键力量【新立电子】
  • 华为hcia——Datacom实验指南——STP工作基本原理及STP/RSTP基本功能配置
  • Python虚拟环境使用指南
  • Http、tcp、https、socket、tomcat、长短连接等总结回顾
  • SpringBoot AI + PgVector向量库 + Openai Embedding模型
  • JAVA安全—手搓内存马
  • JVM--虚拟机
  • 【大模型】什么是蒸馏版大模型
  • wordpress自定义文章模板插件/北京百度推广排名优化
  • 韶关营销型网站建设/网站开发软件有哪些
  • 石碣网站建设/免费合作推广
  • 自己做的网站怎么用qq登入/一份完整的营销策划书
  • 自主建设公司网站/网络软文推广网站
  • 广州网站建设培训学校/广州网站关键词排名