帖子审核队列:单表带标识与双表拆分方案哪个更优?
帖子审核队列:单表 vs 分表方案分析
先明确核心业务需求:
- 消费页面仅展示未完成的审核条目
- 定期补充帖子,允许已完成审核的帖子重新入队(前提是该帖子当前无未完成条目)
下面对比两种方案的优劣,并给出适配建议:
方案一:单表结构(Post_Queue)
用completed_at字段标识状态:NULL表示未完成,非NULL值为完成时间。
| id | post_id | created_at | completed_at |
|---|---|---|---|
| 1 | 112 | 2022-01-01 | 2022-01-02 |
| 2 | 112 | 2022-01-03 | NULL |
优势
- 数据统一,查询直观:同一帖子的所有审核记录(包括多次重新入队的)都存在同一张表,查看历史审核轨迹无需跨表关联,逻辑简单。
- 状态检查便捷:判断某帖子是否有未完成条目时,直接执行
SELECT EXISTS(SELECT 1 FROM Post_Queue WHERE post_id = ? AND completed_at IS NULL)即可,无需跨表操作。 - 字段完整:
completed_at同时记录状态和完成时间,无需额外表存储完成时间信息。
潜在问题
如果数据量极大(千万级以上)且已完成条目占比极高,每次查询未完成条目时需要过滤大量历史数据,可能影响性能。但这个问题可以通过添加索引解决:比如给completed_at单独加索引,或者创建联合索引(post_id, completed_at),既能加速状态查询,也能优化重新入队时的检查逻辑。
方案二:分表结构(Post_Queue + Post_Queue_Completed)
未完成条目存在Post_Queue,已完成条目归档到Post_Queue_Completed。
Post_Queue(未完成)
| id | post_id | created_at | completed_at |
|---|---|---|---|
| 2 | 112 | 2022-01-03 | NULL |
Post_Queue_Completed(已完成)
| id | post_id | created_at |
|---|---|---|
| 1 | 112 | 2022-01-01 |
优势
- 活跃数据查询高效:
Post_Queue仅存储未完成条目,消费页面查询时无需过滤,在数据量极大的情况下性能更优。 - 数据归档清晰:已完成的历史数据和活跃数据物理隔离,便于后续对历史数据进行归档、备份或清理。
劣势
- 逻辑复杂度提升:
- 判断帖子是否可重新入队时,需要先查
Post_Queue确认无未完成条目,再查Post_Queue_Completed获取历史记录,涉及跨表操作。 - 完成审核时,需要将条目从
Post_Queue删除/迁移到Post_Queue_Completed,增加了业务逻辑的步骤。
- 判断帖子是否可重新入队时,需要先查
- 历史查询繁琐:查看某帖子的所有审核记录时,需要联合查询两张表,不如单表直观。
适配建议
- 如果你的队列数据量不大(百万级以内),或者日常需要频繁查询历史审核记录,优先选择单表方案。它的开发和维护成本更低,逻辑更简洁,加合适的索引就能满足性能需求。
- 如果你的队列数据量极大,且未完成条目占比极低(比如不足1%),同时消费页面的查询性能要求极高,可以考虑分表方案,但要做好跨表逻辑的封装和异常处理,避免引入额外的维护负担。
内容的提问来源于stack exchange,提问作者Query
相关产品推荐
相关产品推荐

