1. 程式人生 > >評論系統數據庫設計及實現

評論系統數據庫設計及實現

之一 import 都對 兩個 nic lar amp arr thead

評論系統數據庫設計及實現

需求分析

一般我們瀏覽網站的時候經常能看到如下圖的這種效果(圖片來自CSDN)

技術分享圖片

這種評論層層嵌套,每個評論下面還掛著若幹個對評論的回復。

這種結構類似於樹狀結構,用戶看起來一目了然,也是一種非常主流的評論系統設計。

數據庫設計

在以評論為主的樹形結構中,數據庫的設計非常靈活,可以是單表設計,每個評論都有一個parent_id指向父評論。還可以分開為兩個表,評論一張表,對評論的回復是另一張表。

這裏我使用的是單表設計。

數據表設計如下。由於我開發的是一個新聞系統,所以我就直接以項目舉例。

表字段 ? ? 字段說明 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
commentId 評論的id,自增值,每個評論都對應一個唯一的commentId
newsId ? ? 評論所對應的新聞的id ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
content ? 評論的內容 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
userId ? ? 發出該評論用戶的id ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
parentId ? 指向父評論的id,如果不是對評論的回復,那麽該值為null ?
date ? ? ? 評論產生日期 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

SQL語句:

評論表:

create table if not exists comments
(
? ? commentId bigint auto_increment primary key,
? ? newsId ? ?bigint not null,
? ? parentId ?bigint,
? ? content ? text ? not null,
? ? userId ? ?bigint not null,
? ? date ? ? ?timestamp default current_timestamp(),
? ? foreign key (parentID) references comments (commentId),
? ? foreign key (userID) references users (userId),
? ? foreign key (newsID) references news (newsId)
) charset = utf8mb4;

實現

  • 查詢語句:
SELECT a.commentId,a.newsId,a.parentId,a.newsId,b.nickname,b.avatar,a.content,a.date
? ? ? ? FROM comments AS a,users AS b WHERE a.newsId=#{newsId} AND a.userId=b.userId

為了減少數據庫查詢次數,直接一次將一個新聞下的所有評論都查詢了出來,然後通過程序來編排評論的顯示結構。通過適當的冗余來提高性能也是常用的優化手段之一

  • 評論的實體類

import lombok.Data;
import java.util.Date;
import java.util.List;

@Data
public class Comment {
? ? Long commentId;
? ? Long newsId;
? ? Long parentId;
? ? Long userId;
? ? String nickname;
? ? String avatar;
? ? String content;
? ? Date date;
? ? List<Comment> child;
}

這裏給出一段通過程序來組織所有評論的代碼(為了文章的精簡,只寫邏輯相關的代碼)

public List<Comment> getComments(Long newsId) {
? ? ? ? List<Comment> allComments = commentMapper.getComments(newsId);
? ? ? ? if (allComments == null || allComments.size() == 0) {
? ? ? ? ? ? return new ArrayList<>();
? ? ? ? }
? ? ? ? List<Comment> comments = new ArrayList<>();
? ? ? ? List<Comment> parents = new ArrayList<>();
? ? ? ? for (Comment comment : allComments) {
? ? ? ? ? ? if (comment.getParentId()==null) {
? ? ? ? ? ? ? ? comments.add(comment);
? ? ? ? ? ? ? ? parents.add(comment);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? boolean foundParent=false;
? ? ? ? ? ? ? ? for (Comment parent : parents) {
? ? ? ? ? ? ? ? ? ? if (comment.getParentId() == parent.getCommentId()) {
? ? ? ? ? ? ? ? ? ? ? ? if (parent.getChild() == null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? parent.setChild(new ArrayList<>());
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? parent.getChild().add(comment);
? ? ? ? ? ? ? ? ? ? ? ? parents.add(comment);
? ? ? ? ? ? ? ? ? ? ? ? foundParent=true;
? ? ? ? ? ? ? ? ? ? ? ? //如果對list叠代過程中同時修改list,會報java.util.ConcurrentModificationException 的異常,所以我們需要break,當然break也可以提高算法效率
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (!foundParent) {
? ? ? ? ? ? ? ? ? ? throw new RuntimeException("can not find the parent comment");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return comments;

最終形成的效果圖。
技術分享圖片

接口返回的數據如下:

{
? ? "code": "success",
? ? "message": "獲取評論成功",
? ? "status": "200",
? ? "data": [
? ? ? ? {
? ? ? ? ? ? "id": "236051",
? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? "date": "6小時前",
? ? ? ? ? ? "content": "tt",
? ? ? ? ? ? "userid": "24",
? ? ? ? ? ? "child": []
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? "id": "236028",
? ? ? ? ? ? "author_name": "起航",
? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/7Aq39lKL2jxoWSMgbiaYkQzOR0mOMTm2TLjVhRicYaFXAzg20I8gpcqySYYYQMWG60p8r5kibG3ibiav3CC8Bzibjblw/132",
? ? ? ? ? ? "date": "2019-04-11",
? ? ? ? ? ? "content": "很樸實的文字,又讓人感動唏噓",
? ? ? ? ? ? "formId": null,
? ? ? ? ? ? "userid": "9676",
? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "id": "236032",
? ? ? ? ? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? ? ? ? ? "date": "2天前",
? ? ? ? ? ? ? ? ? ? "content": ":-)",
? ? ? ? ? ? ? ? ? ? "userid": "24",
? ? ? ? ? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? "id": "236040",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "author_name": "God loves me",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/QTU6iasloiaun5OX6ZcZB964vhHLAc5RuIf8kMR3nwIXvy0HibYOe9RJ9o8escDOIj7MB1vica5ibZ2XSDXIibfQMsJA/132",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "date": "1天前",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "content": "為什麽有人會選擇安樂死呢,活著難道比不上痛苦嗎",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "userid": "9663",
? ? ? ? ? ? ? ? ? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "id": "236042",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "date": "1天前",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "content": "如果無法有尊嚴的活著,就難受",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "child": []
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? "id": "236024",
? ? ? ? ? ? "author_name": "倡萌",
? ? ? ? ? ? "author_url": "../../images/gravatar.png",
? ? ? ? ? ? "date": "2019-04-11",
? ? ? ? ? ? "content": "每個人都有自己難以忘懷的過往,昨天今天明天,努力過好每一天!",
? ? ? ? ? ? "userid": "0",
? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "id": "236041",
? ? ? ? ? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? ? ? ? ? "date": "1天前",
? ? ? ? ? ? ? ? ? ? "content": "過好今天,很重要",
? ? ? ? ? ? ? ? ? ? "userid": "24",
? ? ? ? ? ? ? ? ? ? "child": []
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? "id": "236018",
? ? ? ? ? ? "author_name": "Jielinfan",
? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJBXIvvpMo5nXdlk6Mxwia9chS9E8VHGEQbDmyEAx8opRibztDzmpGHpbC3lR5vh8l4fsScZWoyEWyQ/132",
? ? ? ? ? ? "date": "2019-04-08",
? ? ? ? ? ? "content": "祝福老哥。",
? ? ? ? ? ? "userid": "280",
? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "id": "236019",
? ? ? ? ? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? ? ? ? ? "date": "2019-04-09",
? ? ? ? ? ? ? ? ? ? "content": ":-)",
? ? ? ? ? ? ? ? ? ? "userid": "24",
? ? ? ? ? ? ? ? ? ? "child": []
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? "id": "236017",
? ? ? ? ? ? "author_name": "增大網",
? ? ? ? ? ? "author_url": "../../images/gravatar.png",
? ? ? ? ? ? "date": "2019-04-08",
? ? ? ? ? ? "content": "送你一片大海,讓你一帆風順;送你一個太陽,讓你熱情奔放;送你一份真誠,祝你開心快樂;送你一份祝福,讓你快樂天天!",
? ? ? ? ? ? "formId": null,
? ? ? ? ? ? "userid": "0",
? ? ? ? ? ? "child": []
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? "id": "236011",
? ? ? ? ? ? "author_name": "今日新聞",
? ? ? ? ? ? "author_url": "../../images/gravatar.png",
? ? ? ? ? ? "date": "2019-04-07",
? ? ? ? ? ? "content": "文章不錯非常喜歡",
? ? ? ? ? ? "userid": "0",
? ? ? ? ? ? "child": [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "id": "236052",
? ? ? ? ? ? ? ? ? ? "author_name": "Jianbo",
? ? ? ? ? ? ? ? ? ? "author_url": "https://wx.qlogo.cn/mmopen/vi_32/Qib5jkFMntPJnT8b2nyzKicoYSuXLeyl07ia1dianxx1fWcic9hJL4UOEuIJvoWWbx7IFia3olUGqiabZvTe0dmeFBicHQ/132",
? ? ? ? ? ? ? ? ? ? "date": "6小時前",
? ? ? ? ? ? ? ? ? ? "content": "謝謝",
? ? ? ? ? ? ? ? ? ? "userid": "24",
? ? ? ? ? ? ? ? ? ? "child": []
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? }
? ? ]
}

評論系統數據庫設計及實現