点赞功能应分离行为记录与聚合统计:用like_log表存每次操作并防重,like_counter表缓存计数提升读性能,通过异步更新、定时校验和归档策略保障最终一致性和扩展性。

点赞功能的核心是高效记录和统计用户对内容的互动行为,MySQL 中不建议直接在主表(如文章表)里用 like_count 字段做累加更新,因为高并发下容易产生锁竞争和数据不一致。更合理的做法是分离「行为记录」和「聚合统计」,用两张表协同完成。
1. 点赞行为表(like_log)——记录每一次真实操作
这张表用于完整、可追溯地保存用户点赞动作,是业务审计和反刷的基础。
-
字段设计建议:
id(自增主键)、user_id(点赞人)、target_type(被点赞对象类型,如 'post'/'comment')、target_id(被点赞对象ID)、created_at(时间戳) -
关键约束:联合唯一索引
(user_id, target_type, target_id),防止重复点赞;普通索引(target_type, target_id)支持快速查某条内容被赞了几次 -
注意点:不存“取消点赞”,而是用“状态字段”或“软删除”。更推荐用独立的
is_cancelled布尔字段,默认 false,取消时 update 为 true —— 这样保留行为痕迹,也方便后续做活跃度分析
2. 点赞计数表(like_counter)——缓存聚合结果,提升读性能
这张表不是必须实时精确,而是作为高频读取的缓存层,由后台任务或触发器异步维护。
-
字段设计建议:
target_type、target_id(联合主键)、count(当前有效点赞数)、updated_at -
更新时机:用户点赞/取消时,同步执行
INSERT ... ON DUPLICATE KEY UPDATE count = count + VALUES(delta),其中 delta 是 +1 或 -1;也可用定时任务每分钟从like_log汇总一次,降低写压力 -
优势:避免每次查文章详情都
COUNT(*) FROM like_log WHERE ...,尤其当 log 表达千万级后,count 走索引也慢;同时支持快速分页展示“最多点赞的10篇文章”这类需求
3. 读写分离与一致性保障
点赞是典型的“读多写少+最终一致”场景,不必强求秒级精准。
-
前端展示点赞数时,优先读
like_counter;若需绝对准确(如用户刚点完赞立刻刷新),可加缓存标记或短暂降级为查 log 表 - 后台补偿机制很重要:定期比对
like_counter和like_log的统计结果,修复偏差;例如每天凌晨跑一个 SQL:SELECT target_type, target_id, COUNT(*) FROM like_log WHERE is_cancelled = false GROUP BY target_type, target_id,再批量更新 counter 表 - 如果业务允许,甚至可以去掉
like_counter,只靠 Redis 的HINCRBY做实时计数,MySQL 仅保留日志表 —— 更轻量,适合中小流量项目
4. 扩展性考虑:冷热分离与归档
点赞日志长期积累会非常庞大,但多数查询集中在近30天数据。
- 按月分表或分区(如按
created_atRANGE 分区),提升大表查询和清理效率 - 历史日志(如6个月前)可归档到低频存储(如 MySQL 归档库、ClickHouse 或对象存储+离线分析),不影响线上服务
-
like_counter表本身数据量小,无需分表,但建议加updated_at索引,便于按热度排序或清理过期计数(比如已删除的内容对应的计数行)










