MySQL: MySQL数据库设计与范式理论
最后更新:2026-08-26
好的数据库设计是系统成功的基石——设计不好,后患无穷。
本课讲解数据库设计的理论和实践。
1. 你将学到
- 数据库设计流程
- ER 图设计
- 范式理论(1NF→BCNF)
- 反范式设计
- 命名规范
2. 设计流程
graph TB
A[需求分析] --> B[概念设计 ER图]
B --> C[逻辑设计 表结构]
C --> D[物理设计 索引/分区]
D --> E[实施部署]
E --> F[运维优化]
3. 范式理论
| 范式 | 要求 | 示例 |
|---|---|---|
| 1NF | 字段不可再分 | 电话号不能存多个 |
| 2NF | 消除部分依赖 | 非主键字段完全依赖主键 |
| 3NF | 消除传递依赖 | 非主键字段不能依赖其他非主键 |
| BCNF | 每个决定因素都是候选键 | 更严格的 3NF |
▶ 示例:3NF 设计
SQL
-- ❌ 违反 3NF(部门名依赖部门ID,不是直接依赖员工ID)
CREATE TABLE employees_bad (
id INT PRIMARY KEY,
name VARCHAR(50),
dept_id INT,
dept_name VARCHAR(50) -- 传递依赖
);
-- ✅ 符合 3NF
CREATE TABLE departments (
id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES departments(id)
);
4. 反范式设计
有时为了性能,故意违反范式。
| 场景 | 反范式方式 | 原因 |
|---|---|---|
| 频繁 JOIN | 冗余字段 | 减少 JOIN |
| 统计查询 | 计算列 | 避免实时计算 |
| 报表 | 汇总表 | 提升查询速度 |
5. 命名规范
| 规范 | 推荐 | 避免 |
|---|---|---|
| 表名 | snake_case, 复数 | 单数、驼峰 |
| 字段名 | snake_case | 驼峰、中文 |
| 主键 | id | userId |
| 外键 | table_id | customerId |
| 索引 | idx_table_col | table_col_idx |
6. ER 图设计
erDiagram
CUSTOMERS ||--o{ ORDERS : places
ORDERS ||--|{ ORDER_ITEMS : contains
PRODUCTS ||--o{ ORDER_ITEMS : includes
CUSTOMERS {
int id PK
string name
string email
}
ORDERS {
int id PK
int customer_id FK
decimal amount
date order_date
}
PRODUCTS {
int id PK
string name
decimal price
}
❓ 常见问题
Q 一定要遵循 3NF?
A 大多数情况是。但读多写少的场景可以适当反范式。
Q 字段用什么类型?
A 主键用 BIGINT,金额用 DECIMAL,时间用 TIMESTAMP,文本用 VARCHAR。
Q 表名用单数还是复数?
A 推荐复数(users, orders),表示"一组记录"。
Q 三范式一定要遵守吗?
A 不一定。高并发查询场景可反范式,适当冗余减少 JOIN。
Q ER图用什么工具?
A MySQL Workbench(正向/逆向工程)、draw.io(在线免费)、dbdiagram.io(代码生成ER图)。
📖 小节
- 设计流程:需求→ER图→表结构→索引→部署
- 范式:1NF(不可再分)→2NF(消除部分依赖)→3NF(消除传递依赖)
- 反范式:为性能适当冗余
- 命名规范:snake_case,主键 id,外键 table_id
📝 作业
-
基础题(难度⭐):设计一个博客系统的 ER 图。
-
进阶题(难度⭐⭐):将一个 1NF 表规范化到 3NF。
-
挑战题(难度⭐⭐⭐):设计一个电商数据库,包含用户、商品、订单、支付表。