共计 2526 个字符,预计需要花费 7 分钟才能阅读完成。
1、概述
评论性能曾经成为 APP 和网站开发中的必备性能。本文次要介绍评论性能的数据库设计。
评论性能最次要的是发表评论和回复评论(删除性能在后盾)。评论性能的拓展性能体现有以下几方面:
(1)单篇文章的评论数量和信息展现;
(2)从工夫维度,依照工夫顺叙的形式展现动静的用户评论信息;
(3)不同栏目,不同模块,不同工夫维度的评论排行展现;
(4)精髓评论的独自举荐和聚合展现;
(5)评论后间接分享到绑定的第三方平台;
(6)点赞数、回复数等维度的排行等。
评论的后盾治理:
(1)删除;
(2)举荐;
(3)精髓;
(4)屏蔽,敏感关键字的库的欠缺、主动屏蔽或者替换性能。
本篇文章次要剖析几种客户端评论数据表的设计。
2、数据表设计
2.1 一问一答模式
(1)需要剖析
大部分 APP 采纳简略的评论设计即可,即是一问一答模式,比方微信朋友圈的评论性能的设计。如:
徐志胜:怎么回事?
何广智 @徐志胜:你就是一条舔人的海狗!
这种设计简略、间接,也满足了用户评论、回复的根本要求,对于没有大量用户评论的 APP 需要足够。
(2)数据库设计
这种场景下个别评论较少,评论不沉闷,能够不辨别评论和回复,对立看成评论。区别是,有些评论是间接评论主题,而有些是 @其余用户,应用一张表就能够达到成果,评论表设计如下:
表字段 | 字段阐明 |
---|---|
id | 主键 |
topic_id | 主题 id |
topic_type | 主题类型 |
content | 评论内容 |
from_uid | 评论用户 id |
to_uid | 评论指标用户 id |
topic_type:为了能复用评论模块,咱们引入这个字段来辨别主题的类别。
from_uid:示意评论人的 id,通过该 id 咱们能够检索到评论人的相干信息。
to_uid 是评论指标人的 id,如果没有指标人,则该字段为空
出于性能的思考,往往咱们会冗余评论人的相干信息到评论表中,比方评论人的昵称、头像,指标用户也是如此。这样一来咱们就只用查问单表就能够达到显示的成果
有时,指标用户有多个,那么能够将 to_uid 字段批改为 to_uids,保留时用分隔符来宰割用户 id,而指标用户的信息再去查问缓存或者数据库。也能够简略的将多个指标用户的信息一起存成 json 格局,能够应酬简略的展示需要。
2.2 评论为主模式
(1) 需要剖析
如果以评论为主的显示模式,相似于上面的 CSDN 的评论显示模式:
这里将评论分为评论和回复,所有评论均挂在评论上面,相似于树状构造。
(2)数据库设计
在以评论为主的树形显示状况下,数据库的设计非常灵便,能够应用单表,增加一个 parent_id 字段来指向父评论,须要嵌套查问。
同时也能够将评论拆分为评论表和回复表,评论挂在各种主题上面,而回复挂在评论上面。
评论表设计如下:
表字段 | 字段阐明 |
---|---|
id | 主键 |
topic_id | 主题 id |
topic_type | 主题类型 |
content | 评论内容 |
from_uid | 评论用户 id |
回复表设计:
表字段 | 字段阐明 |
---|---|
id | 主键 |
comment_id | 评论 id |
reply_id | 回复指标 id |
reply_type | 回复类型 |
from_uid | 回复用户 id |
to_uid | 指标用户 id |
因为咱们拆分了评论和回复,那么评论表就不再须要指标用户字段了,因为评论均是用户对主题的评论,评论表的设计更佳简洁了。
回复表增加了一个 comment_id 字段来示意该回复挂在的根评论 id,这样设计也是出于性能方面的思考,咱们能够间接通过评论 id 一次性的找出该评论下的所有回复,而后通过程序来编排回复的显示构造。通过适当的冗余来进步性能也是罕用的优化伎俩之一。
reply_type:示意回复的类型,因为回复能够是针对评论的回复 (comment),也能够是针对回复的回复 (reply),通过这个字段来辨别两种情景。
reply_id:示意回复指标的 id,如果 reply_type 是 comment 的话,那么 reply_id=commit_id,如果 reply_type 是 reply 的话,这示意这条回复的父回复。
2.3 网易新闻盖楼模式
(1)需要剖析
这种场景中评论和回复是同级显示的,回复不在显示构造上不必挂在一个评论上面。双表的设计在这里就不太适合了,因为波及到评论和回复的混排,应用双表则会导致查问的逻辑过于简单。所以倡议还是采纳单表的设计,不辨别评论和回复会简化应用层的逻辑。咱们对立都看成评论,而有些评论是能够援用其余评论的。
(2)数据库设计
自己举荐采纳闭包表的设计,例如:
comment 表设计:
表字段 | 字段阐明 |
---|---|
id | 主键 |
topic_id | 主题 id |
topic_type | 主题类型 |
content | 评论内容 |
from_uid | 评论用户 id |
parent_child 表:
表字段 | 字段阐明 |
---|---|
parent_id | 父 id |
child_id | 子 id |
comment 表保留所有评论内容,而 parent_children 表则记录评论表中各个评论的父子关系。
查问时往往会依照工夫排序,咱们能够间接按 id 或者创立工夫降序排列查问 comment 表即可。如果用户想查问一条评论的残缺援用,则能够通过 parent_children 来找到对应的门路。
闭包表在查问时十分不便,然而插入的性能稍差,因为除了插入评论表以外,还须要把该条评论所有的父子关系插入到父子关系表中。插入性能会随着评论层级的加深而线性降落。
3、数据库优化
如果你的零碎每天都会领有成千上万条评论,那么单表的设计必定是不行,优化的形式有以下几种思路。
(1)分库分表。分库分表是最为罕用也最无效的优化形式,倡议依照主题来分库分表。这样同一个主题上面的评论就会落到同一张表里,防止了跨表查问。
(2)适当的数据冗余。如果你须要显示评论人的相干信息,那么在插入评论时就把这些信息写入评论表中,防止屡次查问。实际上,如果是纪录数据,都能够冗余对应的数据信息,因为它们的数据的实时行和一致性要求并不高。
(3)附加幂。数据只容许单项操作。因为从幂性的要求来说,每个赞全都是一条记录。评论的赞数如果都从点赞表中统计得出,那么性能开销会非常微小,而且点赞如此轻量级的一个操作肯定会加剧点赞表的竞争操作。所以倡议间接在评论表中增加一个 like_count 的计数器,该字段只增不减。客户端,能够设置勾销成果。
(4)热门评论加缓存。相似于网易新闻的热门评论,读取频度十分高,能够专门开接口做缓存。