MySQL 系统学习 第五阶段:企业级 MySQL 实战开发 第四章:博客 / 论坛数据库设计 一、一个博客系统有哪些业务以一个典型博客系统如 CSDN、掘金、知乎专栏为例主要业务有用户注册 │ 发布文章 │ 文章分类 │ 添加标签 │ 发表评论 │ 点赞 │ 收藏根据业务我们先抽取实体。二、抽取业务实体可以得到以下实体User用户 Article文章 Category分类 Tag标签 Comment评论 Favorite收藏 Like点赞接下来分析它们之间的关系。三、实体关系图User / | \ / | \ ▼ ▼ ▼ Article Comment Favorite │ ▼ Category Article │ ▼ Article_Tag ▲ │ Tag Article │ ▼ Like关系如下关系类型用户 → 文章一对多分类 → 文章一对多文章 → 评论一对多文章 ↔ 标签多对多用户 ↔ 文章点赞多对多通过 Like用户 ↔ 文章收藏多对多通过 Favorite四、用户表userCREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), nickname VARCHAR(50), avatar VARCHAR(255), create_time DATETIME );保存用户名昵称头像五、文章表articleCREATE 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分类例如前端 后端 数据库 人工智能SQLCREATE TABLE category ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) );一个分类可以拥有很多文章。例如数据库 ↓ MySQL Redis MongoDB因此Category ↓ Article 一对多七、标签表tag标签例如Vue NestJS Java MySQL DockerSQLCREATE TABLE tag ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) );八、为什么标签是多对多⭐⭐⭐⭐⭐例如文章NestJS MySQL 开发可以有NestJS MySQL TypeORM三个标签。同时MySQL标签又可以属于MySQL索引 MySQL事务 NestJSMySQL很多文章。所以Article ↕ Tag是多对多。九、中间表 article_tag多对多必须中间表。CREATE TABLE article_tag( article_id BIGINT, tag_id BIGINT );例如article_idtag_id111213表示文章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_id1;十三、为什么点赞和收藏不用布尔字段错误设计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记录为什么实体一条关系按关系数量保存