计数用双列表(如点赞表)的主键设计疑问:需新增自增主键吗?
关于点赞表主键设计的建议
嘿,这个问题问到点子上了,我来帮你一步步理清~
首先得先纠正一个误区:绝对不能把post_id设为主键。因为同一篇帖子会被多个用户点赞,主键要求唯一值,这样插入第二条相同post_id的记录时直接就会报错,完全不符合业务需求。
接下来咱们分情况讨论是否需要新增自增主键:
情况1:业务逻辑简单,仅记录「用户-帖子」的点赞关系
如果你的likes表只需要实现“用户点赞帖子”“统计帖子点赞数”这两个核心功能,并且要避免同一个用户重复点赞同一篇帖子,那最优方案是把(user_id, post_id)设为复合主键(或者给这两个字段加唯一约束)。
这么做的好处:
- 天然保证了数据唯一性,不会出现同一用户重复点赞同篇帖子的脏数据;
- 复合主键本身就是一个索引,当你执行
SELECT COUNT(*) FROM likes WHERE post_id = ?这种计数查询时,数据库可以直接利用这个复合索引快速聚合统计,效率非常高; - 取消点赞时,直接通过
DELETE FROM likes WHERE user_id = ? AND post_id = ?就能精准定位记录,同样因为有索引加持,速度很快。
情况2:业务有扩展需求,需要单独操作单条点赞记录
如果后续你的业务可能要增加点赞时间(created_at)、支持取消点赞(软删除标记),或者需要针对某一条点赞记录做其他操作,那可以新增一个自增主键(比如like_id,INT类型自增)。
但注意:即使加了这个自增主键,依然必须给(user_id, post_id)添加唯一约束,防止重复点赞的脏数据。同时,为了保证统计post_id数量的效率,最好给post_id单独建一个索引,或者创建(post_id, user_id)的复合索引,这样计数查询依然能高效执行。
关于查询计数效率的补充
不管选择哪种主键方案,只要有合适的索引,统计post_id数量的速度都不会有问题。复合主键本身就自带索引,而自增主键配合单独的post_id索引,也能让数据库快速定位到目标数据,不需要全表扫描。
总结一下:
- 禁止把post_id设为主键,会导致数据插入冲突;
- 简单业务用
(user_id, post_id)复合主键,既安全又高效; - 有扩展需求就加自增主键,但别忘了加
(user_id, post_id)的唯一约束和对应的索引。
内容的提问来源于stack exchange,提问作者SomeBeginner
相关产品推荐
相关产品推荐

