0%

20221104-积分设计

积分表结构设计

需求

  • 记录积分行为来源
  • 允许撤销用户积分
  • 个人中心有展示总积分
  • 未来积分可以兑换商品
  • 未来积分逐条过期机制

分析

记录积分行为来源

  • 需要增加行为枚举类,并且记录该行为对应的表主键,比如发帖需要对应发帖的内容 id
  • 行为增加的分数,考虑到变动很少,可以放在代码中。如果后期确认该需求经常变动,需要建立对应的表结构,映射该枚举数据
1
2
3
4
5
6
7
8
9
10
11
12
// 积分枚举
enum ScoreSourceTypeEnum {
LIKE = 1,
COMMENT = 2,
// ...
}
// 积分对应分数
const ScoreSourceTypeMap = new Map({
[ScoreSourceTypeEnum.LIKE]: { score: 5, title: "点赞" },
[ScoreSourceTypeEnum.COMMENT]: { score: 10, title: "评论" },
// ...
});

允许撤销用户积分

  • 撤销用户积分不能修改原始数据,应增加一条新纪录记录该行为,积分记录表允许负值或新建一个表记录数据(先采用允许负值方案)
  • 撤销用户积分需要增加操作人,撤销的原因两个字段
  • 增加一个撤销用户积分的行为,行为对应的主键为对应的积分记录 ID

积分逐条过期机制

  • 积分记录表增加剩余积分字段,默认等于当前积分
  • 用户消费积分时,判断剩余积分字段相加是否满足需求,如果满足,按时间倒序挨个去扣除剩余积分字段,直到扣除完毕
  • 统计用户积分时,SUM(剩余积分)
  • 每天跑一次定时任务,每次用户积分过期,剩余积分字段设置为 0

个人中心展示总积分

  • 每次查询用户的积分数据,都需要 sum 方法,如果数据量多,性能会比较差
  • 是否需要直接统计用户的积分,每次插入或删除去修改该数据
  • 如果需要用户总积分,应独立于用户模块,新建一张表,统计用户总积分,以及用户积分相关数据

未来积分可以兑换商品

  • 积分记录表增加商品兑换的行为,并记录订单 id

其他

  • 并发问题(如果用户同时访问数据,一边增加一边消费,是否需要在数据库加锁,或使用单个消息队列来实现)
  • 积分异常(如果突然出现大批量积分发放,每天应有积分监控功能,每日发放积分、扣减积分,总积分数据)

表结构

用户积分记录表

字段 类型 含义
id primary key 主键
uid bigint 用户 id
source_type tinyint 积分来源类型
source_id int 积分来源 id
socre int 分值
rest_score datetime 剩余积分
action_uid bigint 操作人
reason varchar 原因
exprie_time datetime 过期时间
create_time datetime 创建时间
update_time datetime 更新时间
delete_time datetime 删除时间

用户积分表(暂时不使用,数据库无法支撑再考虑)

字段 类型 含义
id primary key 主键
uid bigint 用户 id
socre int 分值
create_time datetime 创建时间
update_time datetime 更新时间
delete_time datetime 删除时间