记录用户的连续登录天数
技术栈
- Redis的bitmap: 100w+的日活用户时
- Redis的sortedSet:10W+的日活用户时
- Mysql: 10W的日活用户时
简述
- bitmap:每个月最多31天,即31bit,每一位表示第N天是否登录的状态:0-未登录/1-已登录
- setbit uid1:2025:6 25 1 (表示uid为1的用户在2025年6月份的25号登录)
- getbit uid1:2025:6 25 (获取uid为1的用户2025年6月份25号是否登录)
- bitcount uid1:2025:6 (获取uid为1的用户2025年6月份的登录天数)
- 要获取当前连续登录的天数则需要代码实现,redis不能直接获取
- sortedSet,ZADD添加时将当前日期当成score记录,获取时通过ZRangeByScore获取完整的数据,后端做连续登录天数的判断。
代码实现:python
import redis, calendar
from datetime import datetime,date
re = redis.Redis(host='127.0.0.1', port=6379, db=0)
def getDays(year, month):max_days = calendar.monthrange(year, month)[1]print("%d年%d月份的最大天数为: %d" % (year, month, max_days))return max_days
def init(uid, year, month, day):key = 'sign:%d:%d:%d' % (uid, year, month)if re.exists(key) == 0: maxDays = getDays(year, month)for i in range(1, maxDays+1):re.setbit(key, i, 0)print('初始化' , key, i)re.setbit(key, day, 1)
def static(uid, year, month, day):cc = 0key = 'sign:%d:%d:%d' % (uid, year, month)for i in range(1, day+1):res = re.getbit(key, i)if res == 0:cc = 0else:cc += 1return cc
def getAll(uid, year, month):key = 'sign:%d:%d:%d' % (uid, year, month)return re.bitcount(key) try:today = str(date.today())year, month, day = list(map(int, today.split('-')))uid = 1init(uid, year, month, day)cc = static(uid, year, month, day)all = getAll(uid, year, month) print('uid:%d 本次连续签到的次数为:%d, %d 月份的签到次数为:%d' % (uid, cc, month, all))
except Exception as e:print(f"连接失败: {e}")