相信大家在平常的系统开发中,或多或少会涉及到一些评论系统的设计。小到某些工具自己做一些备注(实际上也可以理解为评论),大到类似淘宝天猫这种,都需要一些评论的支撑。

当然,评论有简单,也有复杂:

  • 简单的当然就是只有一层的回复了,不能对回复进行另外的回复,类似现在很多迷你社区带的@系统,可以把它看成是只有单层的回复。
  • 稍微更进一步的就是可以对回复进行评论的,类似现在的很多XX头条就是这样的
  • 稍微更进一步的是可以对回复进行回复,即类似引用,但只可以是单层的,如朋友圈。再复杂一点就是可以多层级的回复了,网易的盖楼就是这样的实现,它们的设计可以类似,只是一个字段存放的内容的多好而已。

下面我们就针对上面的几种评论系统作一下描述,当然,只是个人之见,如有不对,还请指出。

单层回复

单层回复就是像很多微型社区里面的@,这个可以简单地理解为回复。@只是在保存的时候使用正则进行相关的匹配,给那些被@的用户发通知。

column type comment
id bigint 主键ID
uid bigint 用户ID
biz_id bigint 业务ID
content text 评论内容
biz_type tinyint 业务类型
create_time timestamp 创建时间
modify_time timestamp 修改时间
deleted tinyint 是否被删除

表结构大概就如上了,当然,很多东西还是要根据业务来增减的,比如回复可以发图片,那么把图片单独出来放在一个字段会容易处理得多。

回复可以评论

这是回复的进化版,它可以对回复进行评论,而用户还可以对评论进行评论,类似现在的一些XX头条基本上都是这样的。

column type comment
id bigint 主键
uid bigint 用户ID
biz_id bigint 业务ID
biz_type tinyint 业务类型
content text 评论内容
create_time timestamp 创建时间
modify_time timestamp 修改时间
deleted tinyint 是否被删除
comment_id bigint 回复ID
parent_id bigint 父ID

表结构大概跟上面的基础版类似,只是增加了一个comment_id,它用于记录需要评论的回复ID(只有是评论的情况下才有值),而parent_id用于记录评论的父评论ID,只有当对评论进行评论的时候,这个值才会大于0。

无限级回复(朋友圈也类似,只是有限制层级为1级)

很多人会感兴趣网易那种盖楼的评论的实现,实际上可以理解为是单个回复的进化版,只是它把所有引用的回复的ID记录下来了,在展示的时候进行显示出来而已。

column type comment
id bigint 主键
uid bigint 用户ID
biz_id bigint 业务ID
biz_type tinyint 业务类型
content text 评论内容
create_time timestamp 创建时间
modify_time timestamp 修改时间
deleted tinyint 是否被删除
parent_ids text 引用评论ID(按顺序)

这里我们新增的是一个parent_ids列,它用于保存引用的评论ID列表,它的顺序按照发表的评论的时间来排,当我们进行盖楼评论的时候,会拿到之前评论的ID,查到它的parent_ids,合并生成新的parent_ids,然后就可以生成新的评论了。

评论ID->parent_ids->合并新的parent_ids>生成新的评论

设计原因

我们会看到第二种区分评论和回复的设计比第一种和第三种都麻烦一些,而且在查询的时候也要进行区分。而第一种和第三种实际上可以合为一个(如果parent_ids为空,则表示是第一级回复,否则则表示是对回复的引用),但考虑到业务可以会有一些特殊性,在设计的时候尽量应该区分会更好处理一些。