商品评论(评价)功能

1、概述

评论功能已经成为APP和网站开发中的必备功能。本文主要介绍评论功能的数据库设计。

评论功能最主要的是发表评论和回复评论(删除功能在后台)。评论功能的拓展功能体现有以下几方面:

(1)单篇文章的评论数量和信息展示;

(2)从时间维度,按照时间倒叙的方式展示动态的用户评论信息;

(3)不同栏目,不同模块,不同时间维度的评论排行展示;

(4)精华评论的单独推荐和聚合展示;

(5)评论后直接分享到绑定的第三方平台;

(6)点赞数、回复数等维度的排行等。

评论的后台管理:

(1)删除;

(2)推荐;

(3)精华;

(4)屏蔽,敏感关键字的库的完善、自动屏蔽或者替换功能。

本篇文章主要分析几种客户端评论数据表的设计。

2、数据表设计

2.1 一问一答模式

(1)需求分析

大部分APP采用简单的评论设计即可,即是一问一答模式,比如微信朋友圈的评论功能的设计。如:

A:今天天气真好!

B @ A :今天天气确实不错!

1

2

这种设计简单、直接,也满足了用户评论、回复的基本要求,对于没有大量用户评论的APP需求足够。

(2)数据库设计

这种场景下一般评论较少,评论不活跃,可以不区分评论和回复,统一看成评论。区别是,有些评论是直接评论主题,而有些是@其他用户,使用一张表就可以达到效果,评论表设计如下:

表字段   字段说明

id     主键

topic_id 主题id

topic_type    主题类型

content 评论内容

from_uid       评论用户id

to_uid    评论目标用户id

topic_type:为了能复用评论模块,我们引入这个字段来区分主题的类别。

from_uid:表示评论人的id,通过该id我们可以检索到评论人的相关信息。

to_uid 是评论目标人的id,如果没有目标人,则该字段为空

出于性能的考虑,往往我们会冗余评人的相关信息到评论表中,比如评论人的nick、头像,目标用户也是如此。 这样一来我们就只用查询单表就可以达到显示的效果

有时,目标用户有多个,那么可以将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    回复类型

content 回复内容

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表:

表字段   字段说明

id     主键

parent_id      父id

child_id 子id

comment表保存所有评论内容,而parent_children表则记录评论表中各个评论的父子关系。

查询时往往会按照时间排序,我们可以直接按id或者创建时间降序排列查询comment表即可。 如果用户想查询一条评论的完整引用,则可以通过parent_children来找到对应的路径。

闭包表在查询时非常方便,但是插入的性能稍差,因为除了插入评论表以外,还需要把该条评论所有的父子关系插入到父子关系表中。 插入性能会随着评论层级的加深而线性下降。

3、数据库优化

如果你的系统每天都会拥有成千上万条评论,那么单表的设计肯定是不行,优化的方式有以下几种思路。

(1)分库分表。 分库分表是最为常用也最有效的优化方式,建议按照主题来分库分表。 这样同一个主题下面的评论就会落到同一张表里,避免了跨表查询。

(2)适当的数据冗余。 如果你需要显示评论人的相关信息,那么在插入评论时就把这些信息写入评论表中,避免多次查询。 实际上,如果是纪录数据,都可以冗余对应的数据信息,因为它们的数据的实时行和一致性要求并不高。

(3)附加幂。数据只允许单项操作。 因为从幂性的要求来说,每个赞全都是一条记录。 评论的赞数如果都从点赞表中统计得出,那么性能开销会十分巨大,而且点赞如此轻量级的一个操作一定会加剧点赞表的竞争操作。 所以建议直接在评论表中添加一个like_count的计数器,该字段只增不减。客户端,可以设置取消效果。

(4)热门评论加缓存。 类似于网易新闻的热门评论,读取频度非常高,可以专门开接口做缓存。

python --商品评价---- 数据表结构以及理解的更多相关文章

  1. Django商城项目笔记No.18商品部分-数据表创建

    数据库表设计 在电商中对于商品,有两个重要的概念:SPU和SKU SPU = Standard Product Unit (标准产品单位) SPU是商品信息聚合的最小单位,是一组可服用.易检索的标准化 ...

  2. Zabbix的数据表结构

    看到Zabbix的数据表结构吧,就知道数据量大了 性能问题很让人担忧,不过基于Zabbix数据库导出报表,或自动跑报表的时候,就必须去了解一下zabbix的数据表结构了,得知道XX放在哪才能找到XX, ...

  3. 【转】Informix数据表结构分析资料整理之约束查询代码

    原文地址:http://blog.csdn.net/xqf222/article/details/6271219 本文主要整理了Informix数据库相关系统表数据,已分析整个Informix数据表结 ...

  4. 25 Zabbix系统数据表结构介绍

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 25 Zabbix系统数据表结构介绍 自学Zabbix之路15.1 Zabbix数据库表结构简单解 ...

  5. navicat如何导出mysql数据表结构

    我们在创建数据库时会对字段进行设置,比如类型.长度等,如果字段多的话一个个设置非常麻烦,可以从其他地方已有的表导入数据表结构,怎么操作呢?我们拿navicat导出mysql数据表结构为例: 1.点击“ ...

  6. (笔记)Mysql命令desc:获取数据表结构

    desc命令用于获取数据表结构. desc命令格式:    desc 表名;同样    show columns from 表名;也能获取数据表结构. 举例如下:mysql> desc MyCl ...

  7. phpmyadmin数据表结构没有显示注释列

    新开的一个项目,用phpmyadmin作为图形化操作数据库工具.创建数据表时为其每列添加好注释,浏览数据表内容有显示注释内容,但是查看数据表结构没有显示注释列,不方便直观查看数据表每列的意思. 上网搜 ...

  8. Ecshop数据表结构

    -- 表的结构 `ecs_account_log`CREATE TABLE IF NOT EXISTS `ecs_account_log` (`log_id` mediumint(8) unsigne ...

  9. Activiti学习(二)数据表结构

    Activiti工作流引擎数据库表结构 数据库表的命名 Acitiviti数据库中表的命名都是以ACT_开头的.第二部分是一个两个字符用例表的标识.此用例大体与服务API是匹配的. l        ...

随机推荐

  1. 4,postman和newman的联合使用

    1:下载安装node.js http://nodejs.cn/ 出现版本号证明安装node.js成功 2:安装newman npm install -g newman --registry=https ...

  2. PM学习梳理--搭建产品架构

  3. [C#.net]获取文本文件的编码,自动区分GB2312和UTF8

    昨天生产突然反馈上传的结果查询出现了乱码,我赶紧打开后台数据库,发现果真有数据变成了乱码.这个上传程序都运行3个多月了,从未发生乱码现象,查看程序的运行日志,发现日志里的中文都变成了乱码,然后对比之前 ...

  4. 异步async与await的简单探究

    在学习.net core的过程中,到处见到异步的使用,Task.async.await随处可见.有点疑惑,就去了解了下这个过程是怎样的. 下面是一段代码,去看看是怎么执行的吧. 一.看看异步执行的方式 ...

  5. linux上安装mysql5.7

    1.下载tar包,这里使用wget从官网下载 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.22-linux-glibc2. ...

  6. C++标准库第二版笔记 3 和异常的理解 1

    C++标准库第二版笔记 3 和异常的理解 1 差错和异常(error and exception)的处理 标准异常类(exception class) 定义于 分为: 1.语言本身支持的异常 2.标准 ...

  7. Python Day 10

    阅读目录: 函数 函数的使用 函数的分类 函数的返回值 ##函数 ##函数的定义-----what?----什么是函数: # 函数:完成 特定 功能的代码块,作为一个整体,对其进行特定的命名,该名字就 ...

  8. #2019-2020-4 《Java 程序设计》第九周总结

    2019-2020-4 <Java 程序设计>第九周知识总结 第十一章:JDBC与MySQL数据库 11.1 MySQL数据库管理系统 下载安装: 11.2 启动MySQL数据库服务器 具 ...

  9. 循环调用dll库的界面时,首次正常,再次无响应

    消息循环错误: 在为使用CPaintManagerUI::MessageLoop()的情况下退出,但却发送了PostQuitMessage(0).

  10. 在Linux下部署mysql时,使用group by碰到的问题

    mysql使用group by 的时候报错,错误信息如下: 1055:ER_WRONG_FIELD_WITH_GROUP: Expression #2 of SELECT list is not in ...