## 5.5  博客网站的关系结构设计

本节通过前面章节的博客网站来展示从数据库概念设计到关系数据库结构设计的过程。

### 5.5.1 关系结构设计

基于关系模式设计规则，图5-2-3博客网站的ERD概念模型可以转换以下四个关系表：

- 用户实体转换为用户表User，包含用户ID（u\_id）、用户名（name）、性别（gender）、注册时间（reg\_date）四个属性，其中用户ID（u\_id）为主码；
- 文章实体转换为文章表Doc，包含文章ID（d\_id）、文章标题（title）、文章内容（d\_content）、发表时间（pub\_date）、用户ID（u\_id）、用户名（name）六个属性，其中文章ID（d\_id）为主码，用户与文章之间的一对多写作联系通过在文章表中加入用户ID（u\_id）进行刻画，并且冗余存储了发表该文章的用户名；
- 评论实体转换为评论表Comment，包含评论ID（c\_id）、评论内容（c\_content）、评论时间（com\_date）、用户ID（u\_id）、用户名（name）、文章ID（d\_id）六个属性，其中评论ID（c\_id）为主码，用户与评论之间的一对多写作联系以及文章与评论之间的一对多评价联系通过在评论表中加入用户ID（u\_id），文章ID（d\_id）进行刻画，并且并且冗余存储了发表该评论的用户名。
- 用户与用户之间的多对多关注联系转换成关注表Follow，包含被关注者ID（followee_uid）和关注者ID（follower_uid）两个属性，两个属性共同组成主码。

```bson
博客网站的关系模式设计
用户表：User(u_id, name, gender, reg_date),u_id是主码； 
文章表：Doc(d_id,title, d_content, pub_date, u_id，name), d_id是主码；
评论表：Comment(c_id, c_content, com_date, u_id, name，d_id),  c_id是主码；
关注表：Follow(followee_uid, follower_uid)，followee_uid和follower_uid是主码；
```

上述关系模式中，文章表和评论表中冗余存储了用户名信息。冗余存储数据是否有利于博客网站应用呢？让我们再次回顾一下图5-2-1博客网站的界面和功能。


* 实现博客首页，首先在关注表Follow中读取当前用户关注的所有博主ID（followee_uid），然后根据followee_uid值在文章表Doc中读取所有被关注博主发表的文章，并按时间进行排序。
* 实现博客展示界面，首先根据文章ID（d\_id）在文章表Doc中读取该文章的所有信息以及发表文章的作者名，然后在根据文章ID（d\_id）在评论表Comment中读取该文章的所有评论以及评论者的名字，并按时间进行排序。由于文章表和评论表中分别冗余存储了文章作者名和评论作者名，因此实现博客展示界面不需要额外的查询用户表，避免了文章表与用户表、评论表与用户表之间的连接操作，从而大大提升了整体性能。
* 实现个人主页，首先根据用户ID（u\_id）在用户表User中读取用户的所有信息，在关注表中统计用户的粉丝数以及用户关注的博主数量，然后根据用户ID（u\_id）在文章表中读取该用户发表的所有文章，并按时间顺序进行排序。
* 实现博客编辑界面，直接在文章表Doc中增加一条记录即可。

综合上述分析，我们发现冗余存储用户名（name）不需要过多的存储空间且不会被修改，而且还有利用博客展示界面的性能，因此冗余存储数据是可行。此外，我们发现博客网站经常需要通过用户ID（u\_id）查询文章信息以及评论信息，因此，为了进一步提高性能，可以在文章表Doc的用户ID（u\_id）上创建索引以及在评论表Comment的用户ID（u\_id）上创建索引。

### 练习题

**1**. 请对5.2节第1题（电影网站）构建相应的关系模式，然后再根据应用访问数据库的方式对模式进行优化。

**2**. 请对5.2节第2题（床位分享平台）构建相应的关系模式，然后再根据应用访问数据库的方式对模式进行优化。

**3**. 一个校园学术活动网站。所有学生和老师都可以成为网站的用户，将自己组织的学术活动在网站上发布，比如学术讲座、读书会等等。发布活动时需要指定活动的标题、时间、地点、类别和内容。一旦活动发布，其他用户就可以浏览活动的内容并报名。通常活动有人数限制，活动发起人可以选择部分报名者成为活动参与人，也可以开放给所有报名者参与。活动结束后，参与人可以给活动打分，并写评论记录活动内容。每位用户发起的所有活动将永久被网站记录，其他用户可以随时查看他发起活动的历史，以及平均得分。

请先用ER图为上述场景设计关系数据库模式，然后再根据应用访问数据库的方式对模式进行优化。（提示：需考虑索引的使用。）

[**上一页<<**](chapter5.4.-Rmd) | [**>>下一页**](chapter5.6-D.md)







