当前位置: 首页 > news >正文

MySQL 系统学习 第五阶段:企业级 MySQL 实战开发 第四章:博客 / 论坛数据库设计

一、一个博客系统有哪些业务?

以一个典型博客系统(如 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 Docker

SQL:

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_idtag_id
11
12
13

表示:

文章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。

提高:

查询速度。


🎯 本章核心一句话:

内容管理系统的设计重点在于正确识别实体关系:分类通常是一对多,标签、点赞、收藏等用户行为通常是多对多,并通过中间表维护关系,同时适当冗余统计字段来提升查询性能。


本章思考题

  1. 为什么文章(Article)和分类(Category)是一对多,而不是多对多?
    分类是归属,标签才是描述
  2. 为什么标签(Tag)必须通过article_tag中间表,而不能直接在article表中存"Vue,NestJS,MySQL"
    多值关系必须拆开,符合数据库规范
  3. 为什么点赞(Like)和收藏(Favorite)要设计成独立的关系表,而不能在article表增加is_likeis_favorite字段?
    它们描述用户行为,不属于文章属性
  4. 为什么article_like表已经记录了点赞关系,企业仍然经常在article表中增加like_count字段?
    空间换时间,提高查询性能
  5. 如果一篇文章有3 个标签、20 条评论、100 个点赞、50 个收藏,数据库中分别应该保存多少条articlearticle_tagcommentarticle_likefavorite记录?为什么?
    实体一条,关系按关系数量保存
http://www.jsqmd.com/news/1191380/

相关文章:

  • 【C++】从线性到对数:vector查找算法全解析与实战指南
  • STM32H7-MPU配置实战:Cache策略与DMA性能优化
  • Ultra Librarian云端库与本地离线工具全流程应用指南
  • 老旧建筑地基空洞预警与应急响应:从风险识别到安全撤离实操指南
  • 围棋AI训练工具:点三三开局应对策略的实战部署指南
  • 医疗AI专业性三重验证:数据、临床、指南如何构筑可信底座
  • 古文字识别技术实践:从图像处理到深度学习应用指南
  • Grok:X平台内置的跨模态生产力操作系统
  • 1 jvm基础
  • 从零到一:基于51单片机的智能交通灯系统设计与实现
  • Unity本地化GetLocalizedString失效全解析:从诊断到修复
  • MySQL 系统学习 第五阶段:企业级 MySQL 实战开发 第六章:TypeORM Entity 设计
  • ARM64嵌入式Linux系统FIT uImage启动流程详解与实战
  • 电力系统稳定性的三大支柱:功角、电压与频率稳定的内在关联与工程实践
  • 阿里云轻量服务器+飞书+Qwen3.6-Plus零基础AI助手部署指南
  • 数字逻辑实验进阶——基于Multisim的组合逻辑电路设计与仿真
  • Unity游戏框架GameFramework快速入门:10分钟搭建可运行项目
  • Java控制台交互实战:从Scanner精准捕获到printf优雅格式化
  • 【Multisim仿真实战】从零构建四路抢答器:核心电路模块深度解析与调试技巧
  • 沁恒 CH32V208(二): 深入解析存储映射、零等待机制与多外设时钟配置
  • TK1初始使用全指南:设备校准、行为基线与服务激活三步闭环
  • GaussianSplatting训练教程
  • IO口魔术师:查理复用算法在数码管驱动中的实战与权衡
  • Python爬取笔趣阁小说:从零构建可搜索的批量下载器(附源码)
  • TDA3x SoC硬件设计:引脚、电源与时钟系统实战解析
  • Arduino与TMC2209驱动42步进电机实战:从基础接线到静音控制
  • 从源码到签名:深入解析Android应用获取System权限的两种实践路径
  • DS90UB935-Q1图形发生器配置实战:从寄存器到1080p30彩条信号
  • UE5 AI行为树实战:构建智能感知与追逐系统
  • 基于Java微服务构建淘客返利平台的模块化拆分与演进策略