MySQL 系统学习 第五阶段:企业级 MySQL 实战开发 第四章:博客 / 论坛数据库设计
📅 2026/7/15 4:26:00
👁️ 阅读次数
📝 编程学习
一、一个博客系统有哪些业务?
以一个典型博客系统(如 CSDN、掘金、知乎专栏)为例,主要业务有:
用户注册 │ 发布文章 │ 文章分类 │ 添加标签 │ 发表评论 │ 点赞 │ 收藏根据业务,我们先抽取实体。
二、抽取业务实体
可以得到以下实体:
User(用户) Article(文章) Category(分类) Tag(标签) Comment(评论) Favorite(收藏) Like(点赞)接下来分析它们之间的关系。
三、实体关系图
User / | \ / | \ ▼ ▼ ▼ Article Comment Favorite │ ▼ Category Article │ ▼ Article_Tag ▲ │ Tag Article │ ▼ Like关系如下:
| 关系 | 类型 |
|---|---|
| 用户 → 文章 | 一对多 |
| 分类 → 文章 | 一对多 |
| 文章 → 评论 | 一对多 |
| 文章 ↔ 标签 | 多对多 |
| 用户 ↔ 文章(点赞) | 多对多(通过 Like) |
| 用户 ↔ 文章(收藏) | 多对多(通过 Favorite) |
四、用户表(user)
CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), nickname VARCHAR(50), avatar VARCHAR(255), create_time DATETIME );保存:
- 用户名
- 昵称
- 头像
五、文章表(article)
CREATE TABLE article ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, category_id BIGINT, title VARCHAR(200), content TEXT, status TINYINT, create_time DATETIME );字段说明:
| 字段 | 作用 |
|---|---|
| user_id | 作者 |
| category_id | 所属分类 |
| title | 标题 |
| content | 正文 |
| status | 草稿、发布等状态 |
关系:
一个用户 ↓ 多篇文章属于:
一对多。
六、分类表(category)
分类:
例如:
前端 后端 数据库 人工智能SQL:
CREATE TABLE category ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) );一个分类:
可以拥有:
很多文章。
例如:
数据库 ↓ MySQL Redis MongoDB因此:
Category ↓ Article 一对多七、标签表(tag)
标签:
例如:
Vue NestJS Java MySQL DockerSQL:
CREATE TABLE tag ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) );八、为什么标签是多对多?⭐⭐⭐⭐⭐
例如:
文章:
NestJS + MySQL 开发可以有:
NestJS MySQL TypeORM三个标签。
同时:
MySQL标签:
又可以属于:
MySQL索引 MySQL事务 NestJS+MySQL很多文章。
所以:
Article ↕ Tag是:
多对多。
九、中间表 article_tag
多对多必须:
中间表。
CREATE TABLE article_tag( article_id BIGINT, tag_id BIGINT );例如:
| article_id | tag_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
表示:
文章1:
拥有:
三个标签。
十、评论表(comment)
评论:
属于:
某篇文章。
CREATE TABLE comment( id BIGINT PRIMARY KEY AUTO_INCREMENT, article_id BIGINT, user_id BIGINT, content TEXT, create_time DATETIME );关系:
文章 ↓ 评论 一对多一篇文章:
可以:
1000条评论。
十一、点赞(like)
很多人:
喜欢:
文章:
增加:
like_count其实:
真正:
点赞记录:
应该:
独立。
例如:
CREATE TABLE article_like( user_id BIGINT, article_id BIGINT, create_time DATETIME );为什么?
因为:
需要知道:
谁点过赞。
例如:
Tom ↓ 文章1以后:
取消点赞:
直接:
删除:
这一条记录。
十二、收藏(favorite)
收藏:
也是:
多对多。
CREATE TABLE favorite( user_id BIGINT, article_id BIGINT, create_time DATETIME );以后:
我的收藏:
就是:
查询:
SELECT * FROM favorite WHERE user_id=1;十三、为什么点赞和收藏不用布尔字段?
错误设计:
article is_like is_favorite问题:
这是:
针对:
哪个用户?
点赞:
是:
用户行为。
不是:
文章属性。
例如:
Tom:
点赞。
Jack:
没有。
所以:
不能:
放:
article。
必须:
建立:
关系表。
十四、是否保存点赞数量?
企业:
一般:
既保存:
article_like又保存:
article.like_count为什么?
如果:
每次:
统计:
SELECT COUNT(*) FROM article_like;访问量高时:
性能很差。
所以:
点赞时:
插入 article_like + article.like_count +1取消点赞:
删除 article_like + article.like_count -1这样查询文章列表时,无需每次聚合统计,性能更高。
十五、完整数据库结构
User / | \ / | \ ▼ ▼ ▼ Article Comment Favorite │ ▲ │ │ ▼ │ Article_Like │ │ │ ▼ │ Article_Tag ──────────┘ │ ▼ Tag Article │ ▼ Category十六、本章总结
| 表 | 作用 |
|---|---|
| user | 用户 |
| article | 文章 |
| category | 分类 |
| tag | 标签 |
| article_tag | 文章标签关系 |
| comment | 评论 |
| article_like | 点赞关系 |
| favorite | 收藏关系 |
企业设计最重要的四个思想 ⭐⭐⭐⭐⭐
① 分类是一对多
一个分类:
对应:
多篇文章。
② 标签是多对多
一篇文章:
多个标签。
一个标签:
多个文章。
必须:
中间表。
③ 点赞、收藏属于用户行为
不能:
放:
article必须:
关系表。
④ 数量统计要冗余存储
例如:
like_count comment_count favorite_count view_count放:
article。
提高:
查询速度。
🎯 本章核心一句话:
内容管理系统的设计重点在于正确识别实体关系:分类通常是一对多,标签、点赞、收藏等用户行为通常是多对多,并通过中间表维护关系,同时适当冗余统计字段来提升查询性能。
本章思考题
- 为什么文章(Article)和分类(Category)是一对多,而不是多对多?
分类是归属,标签才是描述 - 为什么标签(Tag)必须通过
article_tag中间表,而不能直接在article表中存"Vue,NestJS,MySQL"?
多值关系必须拆开,符合数据库规范 - 为什么点赞(Like)和收藏(Favorite)要设计成独立的关系表,而不能在
article表增加is_like、is_favorite字段?
它们描述用户行为,不属于文章属性 - 为什么
article_like表已经记录了点赞关系,企业仍然经常在article表中增加like_count字段?
空间换时间,提高查询性能 - 如果一篇文章有3 个标签、20 条评论、100 个点赞、50 个收藏,数据库中分别应该保存多少条
article、article_tag、comment、article_like、favorite记录?为什么?
实体一条,关系按关系数量保存
编程学习
技术分享
实战经验