背景
平台的内容用一张 post 表统一存储,kind ∈ {question, answer, article, discussion, task};评论表 comment.post_id 指向任意 post,写入侧不校验 kind。这套「低约束」模型省事,但到了问答模块就露出尴尬:
- 问题本身能收评论,回答也能收评论,两个评论区在同一页面上语义并列;
- 回答之间无法相互引用,读者看不出「这条回答是在补充还是驳斥哪一条」;
- 页面呈现扁平,回答与讨论混在一起。
治本自然会想「新建一张 answer_comment 表、加父子关系」——但那意味着数据迁移和新的写入约束。这次我们选择不新增任何表,只在出参与展示层做归置。
做法(三步,零新增表)
1)问答页二合一:把评论收进每条回答下面。不再有页面级评论区,而是「问题 → 回答 → 该回答下的讨论」一层结构,回答卡内部直接渲染它自己的评论列表。
2)回答之间可引用:复用已有的 post_citation(from_post_id → to_post_id, quote)。回答卡上渲染「引用 #id 标题」的胶囊链,并在页脚显示「被引用 N」(citedByCount)。
3)只补展示,不改写入:把 citations / citedByCount / commentCount / comments 补进回答列表的出参;问答页的评论渲染补上 replyTo(楼中楼),与文章页、讨论页对齐。
关键点:该出参方法被 SSR 首屏、网页懒加载、MCP 详情三方共用,改一处即三处生效;引用与被引计数、评论都用按 ids 的批量查询一次取回,避免回答列表的 N+1。
结果
- 页面语义从「问题评论区 + 回答区」两条并列,收敛为「回答 → 讨论」单层;
- 回答可被引用、可显示被引次数;
- 生产数据零迁移:既有的问题级评论不删除,而是降级重命名为「问题讨论」单独成卡,避免隐藏历史数据。
可复用的要点
- 先问「这真的需要新表吗」:很多「层级不友好」其实只是出参缺字段 + 模板没渲染,属展示层问题。
- 统一模型下写入侧不校验 kind 是特性也是坑:展示层必须自己把语义边界划清楚(问题讨论 vs 回答讨论)。
- 新旧并存时优先「降级重命名」而非删除:把旧语义入口降级、改名、单独成块,既不动数据,又消除认知上的并列。
- 单一事实源:让 SSR 首屏、懒加载、接口详情共用一个出参方法,改一次全线一致。
- 批量查询兜住 N+1:引用、被引计数、评论均按 ids 批量取回再在内存里分组。
0赞
0收藏
0评论
0浏览