累计连续签到 设计和实现

累计连续签到 设计和实现

  • 最近公司业务上需要实现一个累计连续打卡的功能,现在把打卡设计问题和思路整理一下发给大家

  • 目前搜集到一些基于 Redis 位图 / 关系型数据库的一些方案,可以参考一下,做出最优方案的选择

    • 玩转Redis-京东签到领京豆如何实现
    • 基于Redis位图实现用户签到功能
    • 如何利用 Redis 快速实现签到统计功能
  • 由于需求的复杂,本文还是选择使用关系型数据库实现和存储,因为关系型数据库查询无所不能,哈哈哈哈

功能要求

  • 签到
  • 补签
  • 统计某用户截至今天连续打卡天数
  • 统计某用户在某一天打卡排名
  • 统计某用户截至到某天连续打卡天数
  • 最高连续签到记录

下面直接上一个需求图
累计连续签到 设计和实现_第1张图片

问题难点

  • 怎么用比较好方式去统计连续打卡天数
  • 怎么实现补卡功能以达到连续签到的效果
  • 怎么实现补签后连续天数的统计功能

数据库设计

以下是打卡记录表的设计和实现,我已经去掉了一些业务字段,剩下都是表结构的核心字段

CREATE TABLE mark_record (
    id             BIGINT                  NOT NULL COMMENT 'ID'
        PRIMARY KEY,
    create_time    DATETIME                NOT NULL COMMENT '创建时间',
    update_time    DATETIME                NOT NULL COMMENT '更新时间',
    user_id        BIGINT                  NOT NULL COMMENT '用户ID',
    mark_day_time  INT                     NOT NULL COMMENT '打卡日期 yyyyMMdd',
    day_continue   BIGINT       DEFAULT 0  NOT NULL COMMENT '距离上次打卡相差天数',
    mark_type      TINYINT      DEFAULT 0  NOT NULL COMMENT '补签 0否 1是',
    CONSTRAINT uidx_user_id_mark_day_time
        UNIQUE (user_id, mark_day_time)
)
    COMMENT '打卡签到表';

id/create_time/update_time 表结构的常规字段,简单提醒一下,业务上这些字段也比较重要

  • id 表的唯一主键

  • create_time/update_time 比较重要数据信息字段一般都保留

列举一个比较实用业界数据分页案例:
数据分页翻页时候,防止新增数据导致分页加载出现重复数据,一般做法是当客户端打卡当前页面那瞬间时间戳传过来,上下翻页都是用同一个时间戳,后端查询数据时候只查询小于这个时间戳的数据,大于这个时间戳的数据就不会加载出来了
其他用途就不一一列举了

  • user_id & mark_day_time 组成一个唯一索引

一个用户一天只允许打卡一次,加唯一索引保证数据唯一防止脏数据

  • mark_type 记录打卡类型

区分正常打卡和补卡

  • day_continue 冗余字段 距离上次打卡记录相差天数

以方便统计相关打卡记录数据

代码实现

打卡功能实现

markDayTime 当前打卡签到日期,userId 当前打卡用户 ID

签到功能 SQL

你可能感兴趣的:(数据库设计,签到,Java,数据库设计,Redis,位图)