点赞和收藏需分开建表,因二者业务语义、查询频率与生命周期不同;混用会导致索引低效、权限难控、统计耦合;核心防重靠数据库唯一约束而非应用层判断。
点赞和收藏为什么要分开建表
因为点赞(like)和收藏(favorite)虽然行为相似,但业务语义、查询频率、生命周期都不同。混在一张表里会导致索引低效、权限难控制、统计逻辑耦合。比如用户取消点赞很频繁,但收藏删除率低;又比如「我收藏了哪些文章」要常查,而「谁点过这个评论」可能只在后台用。分开后,
表可以加
联合唯一索引防重复,
表则更适合加
降序索引支持「最近收藏」。
如何避免重复点赞或重复收藏
核心是靠数据库层唯一约束,不是靠应用层判断。否则并发请求下容易写入两条。建表时必须声明:
执行
时,如果已存在相同三元组,MySQL 直接报错
。应用层捕获这个错误,返回「已点过赞」即可。
怎么高效查某篇文章的点赞数和是否被当前用户点过赞
不能每次查都
全表扫描,也不能用两个独立查询(N+1 问题)。推荐用单条 SQL + 条件聚合:
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
这个查询能命中
索引的前缀(
),性能可控。注意:如果
表数据量超千万,建议把计数结果缓存到 Redis,只在点赞/取消时更新缓存和 DB。
收藏表要不要记录来源渠道或设备信息
一般不需要。收藏本质是用户对内容的长期兴趣标记,和操作路径无关。加
或
字段只会增大索引体积、拖慢写入,且几乎没查询场景用到。例外情况只有做反作弊——比如限制同一设备 1 小时内最多收藏 10 篇,这时才需要,但应单独建轻量级风控日志表,而不是污染主收藏表。
实际部署时最容易被忽略的是:没有给
字段加枚举校验或应用层白名单控制。一旦写入非法值如
或拼写错误的
,后续所有按类型聚合的统计都会漏数据,而且很难回溯修复。
likes(user_id, target_type, target_id)favoritescreated_atCREATE TABLE likes (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
target_type VARCHAR(20) NOT NULL COMMENT 'post, comment, reply',
target_id BIGINT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_target (user_id, target_type, target_id)
);INSERT INTO likes (user_id, target_type, target_id) VALUES (123, 'post', 456)ERROR 1062 (23000): Duplicate entry '123-post-456' for key 'uk_user_target'COUNT(*)SELECT
COUNT(*) AS like_count,
MAX(CASE WHEN user_id = 123 THEN 1 ELSE 0 END) AS has_liked
FROM likes
WHERE target_type = 'post' AND target_id = 456;uk_user_targettarget_type, target_idlikessourcedevice_idtarget_type'post_xxx''posst'