用户积分系统怎么设计

用户积分系统怎么设计

  1. 积分总表(User_Point_Wallet)
    作用: 相当于"钱包",只存总额,用于快速读取(展示给用户看)。
java 复制代码
CREATE TABLE user_point_wallet (
    user_id BIGINT PRIMARY KEY,
    total_balance INT DEFAULT 0, -- 当前可用总积分
    version INT DEFAULT 0,       -- 乐观锁版本号
    update_time DATETIME
);
  1. 积分流水表(Point_Flow_Log)
    作用: 相当于"银行流水",记录每一笔增减操作,不可修改,用于对账。
java 复制代码
CREATE TABLE point_flow_log (
    flow_id BIGINT PRIMARY KEY,
    user_id BIGINT,
    amount INT,             -- 变动金额(+100 或 -20)
    type TINYINT,           -- 类型:1-签到,2-购物,3-兑换,4-过期
    ref_id VARCHAR(64),     -- 关联业务单号
    create_time DATETIME
);
  1. 积分明细/分桶表(Point_Detail_Bucket)
    作用: 记录每一笔入账积分的余额和过期时间。
java 复制代码
CREATE TABLE point_detail_bucket (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    initial_amount INT,     -- 初始入账金额(如 100)
    current_balance INT,    -- 当前剩余金额(初始 100,消费后变 80)
    expire_time DATETIME,   -- 过期时间(决定了它的生死)
    status TINYINT,         -- 0-有效,1-已用完,2-已过期
    INDEX idx_user_expire (user_id, expire_time) -- 关键索引:按过期时间排序
);

消费时,基于这张表做 FIFO 扣减。

当用户消费 20 分时:

查询 point_detail_bucket,按 expire_time ASC 排序。

找到第一条快过期的记录(1月入账的),current_balance 够扣就扣,不够就扣完这条再找下一条(递归扣减)。

更新 user_point_wallet 总数。 这就是标准的"账本拆分"逻辑。

怎么高效提醒用户积分快过期了?"

错误解法:实时扫描

每天扫数据库 WHERE expire_time = 明天。 死穴: 5 亿用户扫不动。而且如果用户今天把积分花光了,你明天还发短信说"你有积分快过期",用户会觉得你系统有 Bug。

王者解法:离线计算 + 惰性清理

  1. 提醒策略(T+1 离线计算)

针对 5 亿这种体量,别做实时提醒,成本太高且没必要。

方案: 利用大数据平台(Hive/Spark)。

逻辑: 每天凌晨,把 point_detail_bucket 的快照同步到数仓。在数仓里跑一个 SQL,算出"未来 7 天过期的 Bucket 总额 > 0"的用户清单。

触达(MQ 削峰): 拿到清单后,千万别直接调短信接口!5 亿用户哪怕只有 1% 过期,也是 500 万条短信。必须引入 MQ 进行削峰填谷,控制发送速率(如 5000 QPS),避免早高峰把短信网关打挂。

备选方案(轻量级): 如果公司没有大数据基建,可以退回到 '过期日历表' 方案。建一张表按"过期日期"聚合用户 ID,每天扫描。虽然维护成本高一点,但胜在不需要维护 Hadoop 集群,适合中小体量。

  1. 清理策略(惰性 + 定时)

不要每天去 DB 里执行 UPDATE point_detail_bucket SET status = 过期。

读时触发: 用户查积分时,前端根据 expire_time 过滤掉已过期的,展示"有效余额"。

写时触发: 用户消费时,后端过滤掉过期的 Bucket,只扣有效的。

物理归档: 针对长期不活跃的"垃圾数据",后台低频 Job 慢慢搬运到历史冷库。

相关推荐
喵了几个咪几秒前
Go 语言 CMS 横评:风行 GoWind 对比传统 PHP/Java CMS 核心优势
java·golang·php
fire-flyer几秒前
ClickHouse系列(八):ClickHouse 的 UPDATE / DELETE 正确姿势
大数据·数据库·clickhouse
fire-flyer2 分钟前
ClickHouse系列(七):Materialized View 与多分辨率 Rollup 设计
大数据·数据库·clickhouse·架构
星晨雪海4 分钟前
Spring Boot 常用注解
java·spring boot·后端
码云之上5 分钟前
从 SQL DDL 到 ER 图:前端如何优雅地实现数据库可视化
前端·数据库·数据可视化
AKA__Zas6 分钟前
SQL查询技巧全 Strategy Guide
数据库·sql·学习方法
luoganttcc7 分钟前
华为 的 npu 架构如何 进行 flash attention
数据库·华为
whatever who cares7 分钟前
java/android中单例模式详解
android·java
Chasing__Dreams7 分钟前
Mysql--基础知识点--94.1--嵌套子查询转关联查询
数据库·mysql
qq_283720058 分钟前
Python 操作 MySQL 数据库全解:增删改查、事务、连接池与性能优化
数据库·python·mysql