设计思路
一、数据库MySQL
签到最核心的包含两个要素:
• 谁签到:用户id
• 什么时候签的:签到日期
同时要考虑一些功能要素,比如:
• 补签功能,所以要有补签标示
• 按照年、月统计的功能:所以签到日期可以按照年、月、日分离保存
根据以上条件我们可以设计出保存到数据库的一张签到记录表
id | 主键 |
User_id | 用户id |
year | 签到年份 |
month | 签到月份 |
date | 签到日期 |
is_backup | 是否补签 |
签到一般都会统计该用户本月内的签到次数,连续签到天数,并根据不同连续签到的天数给出不同的积分。那么要统计这些数据,我们首先想到的是设计一个数据表,包括用户id,签到的年月日,用户当日签到就向数据库新增一条记录,在统计连续签到天数,也需要逐个记录去查询。对于一个用户来说,一个月就是三十条记录,当我们的系统人数越来越多后,这张表就会产生非常庞大的数据量,不仅占用磁盘空间,也会极大的影响查询效率。
二、Redis(BitMap)
所以我们采用一种更为简单且节省空间的方法 就是使用redis来进行存储。使用Bit位来表示是否签到。1代表签到 ,0代表未签到
它把每一个bit为对应当月的每一天,用0和1分别标识是否打卡,这种思路称为bitmap(位图)
在后台,要做的事情就是把BitMap中的与签到日期对应的bit位设置为1
另外,为了便于统计,我们计划每个月为每个用户生成一个独立的KEY,因此KEY中必须包含用户信息、月份信息。
一、添加签到记录
使用setBit命令,将天数减1的bit位设置成true
二、查询签到记录
具体实现 通过当月的年月(yyyyMM)字符串,在redis查询当月的签到记录,使用bitField这个命令,从0号索引获取到当前天数的数量的字节,返回一个十进制的数,将十进制的数转化为二进制,如果二进制的位数少于当前天数,就在起始位置补0,缺几个补几个,表示当日未签到