ThinkPHP6实现接口点赞功能需设计独立like_log表并建联合唯一索引,通过Redis缓存点赞数、MySQL原子操作防并发,结合前端置灰与频率限制保障幂等性与性能。

ThinkPHP6 实现接口点赞功能,核心在于设计合理的数据结构、处理并发请求、避免重复操作,并兼顾性能和用户体验。
数据库表结构设计
建议单独建一张点赞记录表,而不是直接在内容表加字段,便于统计、查询和扩展:
- like_log 表:id、user_id(点赞用户)、target_type(如 'article'、'comment')、target_id(被点赞内容ID)、created_at
- 联合唯一索引:
(user_id, target_type, target_id),防止同一用户对同一目标重复点赞 - 如需实时统计,可额外维护一个缓存字段(如文章表的
like_count),但更新走异步或事务保障一致性
接口逻辑实现(控制器示例)
以点赞一篇文章为例,使用 TP6 的 Request 和 Db 类即可完成基础逻辑:
- 接收
target_id和target_type,校验参数合法性(如 ID 是否数字、type 是否白名单) - 获取当前登录用户 ID(通过 token 或 session,推荐用中间件统一解析)
- 用
Db::name('like_log')->where([...])->find()查询是否已点过赞 - 存在则取消点赞(
delete),不存在则新增记录(insert) - 成功后返回最新点赞数(可查表聚合,也可读缓存,推荐 Redis 缓存 + 每次增减更新)
防刷与并发处理
高频点赞场景下,需防止机器人刷赞或并发导致重复插入:
- 前端按钮点击后置灰 + 倒计时,避免用户连点
- 后端用 Redis 锁控制单用户对单目标的操作原子性,例如 key 为
like:u{uid}:t{type}:{tid},过期设为 2 秒 - 更稳妥方式:用 MySQL 的
INSERT ... ON DUPLICATE KEY UPDATE替代先查后插,避免竞态条件 - 敏感操作建议加频率限制(如每分钟最多 10 次点赞),用 Redis 计数器实现
缓存与性能优化
点赞数高频读取,不宜每次都查库:
- 点赞/取消时,同步更新 Redis 中对应目标的点赞数(如
like:article:123) - 接口返回前优先读 Redis,未命中再查 DB 并回填缓存
- 定期(如每天凌晨)用 SQL 统计全量数据校准缓存,防止长期累积误差
- 如需展示“谁点了赞”,可另存一份用户列表(小数据用 Redis Set,大数据分页查表)
不复杂但容易忽略细节,把幂等性、锁机制和缓存更新链路理清楚,就能稳定支撑日常业务需求。

















