微服务设计之带过期时间的积分系统

前言

积分系统设计通常会为用户的积分设置一个有效期,以此提升用户活跃度。例如,2025年1月2日添加的积分记录将在2026年1月2日自动过期。积分项目在处理带有效期的积分时,通过新增"用户当前可用积分明细表"分离积分明细与可用额度。积分过期时,删除可用积分表中的过期记录,并在用户积分流水表中添加过期记录,更新总额表。消费时,优先使用即将过期的积分,按过期时间排序并累加,不足时拆分记录。此方案有效解决积分过期与使用优先级问题,确保数据准确性和用户体验。

数据模型设计

  1. 需要明确定义用户实体和积分实体的数据结构

  2. **积分过期机制:**设计合理的积分时效计算和状态更新规则

  3. **存储与查询优化:**规划高效的数据存储方案,并优化过期积分的查询性能

  4. **定时任务实现:**开发自动执行积分过期处理的定时调度功能

积分表设计

  • 积分优先扣除最早过期的且小面值的积分

  • 每天需要定时扫码可用积分表,将过期积分删除,并在积分记录表标注好过期记录以及扣减积分详情表记录扣减值

  • 积分总额可直接根据可用积分值计算(即使过期积分没即使删除,也可以通过计算过滤来实现)

我们设计三张表,分布是:用户积分总表 user_point,用户积分流水表 user_point_flow_log,用户当前可用积分明细表 user_point_detail。

user_point 用户积分总表

|---------------|--------|---------------------|
| 字段 | 类型 | 描述 |
| id | BIGINT | 主键 |
| user_id | BIGINT | 用户ID |
| total_balance | INT | 总积分 |
| version | INT | 版本号,Optimistic_Lock |

|----|---------|---------------|---------|
| id | user_id | total_balance | version |
| 1 | 1201 | 20 | 1 |
| 2 | 1202 | 200 | 1 |

user_point_flow_log 用户积分流水表:需要将内容展示给用户,让用户知道自己积分的添加、消耗情况。

字段 类型 描述
id BIGINT 主键,流水号ID
user_id BIGINT 用户ID
type INT 积分记录类型
amount INT 积分
action INT 动作 1: 增加 2:扣减
expire_time DATETIME 过期时间
create_time DATETIME 创建时间
remark Varchar(64) 备注

|----|---------|------|--------|--------|-------------|-------------|--------|
| id | user_id | type | amount | action | expire_time | create_time | remark |
| 1 | 1201 | 1 | 10 | 1 | 2026-12-31 | 2025-12-31 | 签到 |
| 2 | 1201 | 1 | 10 | 1 | 2027-01-01 | 2026-01-01 | 签到 |
| 3 | 1201 | 2 | 10 | 2 | 2026-02-24 | 2026-02-24 | 看剧消耗 |

user_point_detail 当前可用积分明细表 :此表对应的是可用的积分记录,当前积分根据此表值计算得出

字段 类型 描述
id BIGINT 主键ID
user_id BIGINT 用户ID
balance INT 积分
expire_time DATETIME 过期时间
create_time DATETIME 创建时间
deleted TINYINT 删除标记

|-----|---------|---------|-------------|-------------|---------|
| id | user_id | balance | expire_time | create_time | deleted |
| 100 | 1201 | 10 | 2026-12-31 | 2025-12-31 | 1 |
| 101 | 1201 | 10 | 2027-01-01 | 2026-01-01 | 0 |

积分过期时,当前可用积分明细表删除过期记录,用户积分流水表添加一条过期明细,积分总额表更新为当前积分总额。

那么积分过期在什么时候触发呢?可以有以下方案:

  1. 可以每天定时进行一次,对所有的会员操作积分过期计算;
  2. 用户当天首次登录时,进行积分计算,排除过期积分;
  3. 每天定时扫描可用积分表1次,将过期积分删除,并及时更新会员积分总额。

第一种方案需要全部遍历会员表,如果会员表太大,效率低下,而且如果会员并没有过期积分,会做许多无效的统计。第二种方案采用被动触发的形式,虽然也会有无效的积分统计,未能及时清理过期积分,但避免了积分的会员表的全表扫描,性能略高。第三种方案从过期积分入手,主动触发,能及时清理过期积分,只针对过期积分,没有无效的统计,性能优于前两种。

积分使用

积分使用策略如下:

  1. 现在要冻结point个积分
  2. 可用积分表的可用积分记录按过期时间升序排列,依次累加积分额度sumPoint直到sumPoint>=point或记录全部遍历完,用recordIds记录符合要求的积分id,用targetRecord记录最后一条积分记录。
  3. 判断sumPoint与point大小,若:
    1. sumPoint < point,则表明用户积分不足,返回false;
    2. sumPoint = point,则表明当前记录刚好等于消耗记录,进行下一步;
    3. sumPoint > point,则表明最后一条记录大于积分额度,需要将其拆分成两条记录,一条用于抵扣(recordId不变,积分额度为(sumPoint-point)),另一条记录积分剩余(额度为最后一条记录的额度-(sumPoint-point),过期时间为最后一条记录的过期时间)。
  4. 处理可用积分表中的记录、积分明细表记录、积分总额。

积分到期提醒

5亿用户的表,积分到期设计,通过大数据计算积分到期的用户,发送MQ,通过消费MQ发送短信提醒用户。

相关推荐
I'mAlex2 小时前
金仓数据库平替MongoDB实操解析:多模融合赋能企业文档数据管理国产化升级
数据库·mongodb·kingbasees·金仓数据库
Pocker_Spades_A2 小时前
MongoDB 远程连不上?用cpolar告别局域网束缚,跨网访问就这么简单
数据库·mongodb
鸽芷咕2 小时前
从底层到实战,金仓多模数据库 MongoDB 兼容的技术实力到底有多强?
数据库·mongodb·金仓数据库
王家视频教程图书馆2 小时前
开源api
数据库
康小庄2 小时前
Java阻塞队列——用法及常用场景
java·开发语言·数据库·spring boot·spring·jetty
m0_528749003 小时前
MySQL CAPI核心操作全解析
数据库·mysql
Apple_羊先森3 小时前
ORACLE数据库巡检SQL脚本--23、检查Oracle数据库中被锁定的数据库对象
数据库·sql·oracle
时光书签3 小时前
数据库服务器磁盘存储扩容
数据库
—Miss. Z—3 小时前
计算机软件资格考试—第六章 数据库基础知识
数据库