项目实训13
1. 背景
本项目中后端使用了两个基本的数据库进行数据的存储,分别是mongodb和mysql,两个数据库均存于云端服务器。本篇文章主要讲一下数据库的设计
2. mysql的设计
mysql分了三个主要的表,分别是用户user表,源图片source表以及上传图片upload表。为了便于统计表,所以每个表都设计了AUTO_INCREMENT
的id字段。user表中的openid是绑定在小程序上的用户唯一标识,其他的就是一些从微信接口获取到的基本信息。source表主要是存储源图片的位置,源图片经过前期的处理,已经全部转化为200*200px的图片,总计1145张,通过后端调度算法返回给前端进行描绘并上传。imageUrl字段是图片的在线地址,存储于nginx服务器上。upload即为用户上传的图片的信息。
下面是创建数据库的ddl语句:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`openid` varchar(255) UNIQUE ,
`nickname` varchar(255) DEFAULT NULL,
`sex` int DEFAULT NULL ,
`headimgurl` varchar(255) DEFAULT NULL ,
`province` varchar(255) DEFAULT NULL ,
`score` int DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `source`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`imageUrl` varchar(255),
`count` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `upload`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`address` varchar(255) NOT NULL,
`openid` varchar(255) ,
`time` datetime ,
`score` int(11) DEFAULT 0,
PRIMARY KEY (`id`),
FOREIGN KEY (`openid`) REFERENCES `user`(`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中FOREIGN KEY (openid
) REFERENCES user
(openid
)给upload的openid设置了外键,避免数据错误。
3. mongodb的设计
mongodb同样是分了三个表,该数据库主要是负责内容管理部分的存储,由于nosql数据库在存储非结构化数据方面的优势,所以项目中的社区部分采用的是nosql存储。包括帖子post、一级评论comment以及一个用于实现mongo自增id的incr表。
其中incr表的作用在第7篇博客中有写到,https://blog.csdn.net/weixin_45774350/article/details/124769587
以下是post对应的实体类的定义:
package com.example.guke.entity;
import com.example.guke.annotation.AutoDec;
import com.example.guke.annotation.AutoInc;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;
/**
* @program: GuKe
* @description: 社区的帖子类, 内含多个回复,类似于百度贴吧的形式
* @author: NiuYiq
* @date: 2022-04-04 16:30
**/
@Data
@Document(value = "post")
public class Post
{
@AutoInc
private long postId; // 帖子的id
private String owner; // 帖子的发起人的所有者 --- openid
@NotBlank
private String title; // 帖子的标题
private Date time; // 发布时间
// private List<CommentToPost> comments; // 用户跟帖
@AutoDec
private int commentCount; // 评论数量
private List<String> likes; // 由于使用的是nosql,所以这里的like不需要再分一个表出去了
// private List<String> annexes; // 博客提供的附件
}
一级评论的定义:
@Data
@Document(value = "commentToPost")
public class CommentToPost
{
@AutoInc
private long C2Pid; // 评论的id
private String owner; // 评论的用户的openid User.openid
private String content; // 用户评论的正文内容
private long belong; // 属于哪一条博客的评论 Post.id
private List<CommentToComment> comments; // 评论下的评论列表
private Date time; // 发布时间
private List<String> likes; // 点赞列表,存的是点赞用户的openid
}
二级评论的定义:
@Data
public class CommentToComment
{
private long C2Pid; // 对应的一级评论的id
private long C2Cid; // 二级评论自身的id
private String owner; // 评论的用户的openid User.openid
private String content; // 评论的正文
private String replyTo; // 回复的哪一个人 默认为回复的层主
private Date time; // 发布时间
}
在mongo数据库中,二级评论不再分出一个表,而是直接存储在一级评论中,当成数组类型进行存储。所以在存取非常频繁的情况下,nosql的性能比多表查询的关系型数据库更好。