6. 数据库设计
数据库设计旨在以规范、高效方式组织数据,满足业务需求并兼顾性能。本章聚焦数据依赖、规范化、ER 建模与系统化设计流程。
6.1 数据依赖与范式
数据依赖类型
- 函数依赖(Functional Dependency, FD):属性集 X 的值决定属性集 Y 的值,记作 X → Y,是设计中最重要的依赖。
- 多值依赖(MVD):某属性决定一组独立的值集合,涉及 4NF/5NF。
- 连接依赖(JD):无损连接分解约束,常用于验证模式拆分的正确性。
第一范式(1NF)
要求所有属性取值原子化,不能含重复组或嵌套结构。例如将“课程列表”拆分为多行单课程记录。
6.2 规范化层级
| 范式 | 条件 | 常见问题 | 解决策略 |
|---|---|---|---|
| 1NF | 属性原子 | 字段包含多值 | 拆分为多行或单独表 |
| 2NF | 满足 1NF,且所有非主属性完全依赖主键 | 复合键的部分依赖 → 更新/插入/删除异常 | 将部分依赖字段拆表,如 S 与 SC |
| 3NF | 满足 2NF,且不存在非主属性对主键的传递依赖 | 传递依赖导致冗余 | 拆分传递依赖,如 EMP/ SAL |
“一事一地”原则:每个事实只在一个位置存储,避免冗余与异常。
6.3 ER 模型与 ER 图
- 基于数据字典与业务流程,识别实体、属性与关系。
- 绘制 ER 图(实体、联系、基数、约束),作为概念模式,与用户沟通确认。
- 工具:ERWin、Rose、PowerDesigner 等。
6.4 设计方法
面向过程
- 按业务凭证/报表直接设计表结构,开发速度快但忽视数据本身关系。
- 难以适应需求变化,适用范围有限。
面向数据
- 以数据及其内在联系为中心,深入分析实体与约束。
- 能满足当前与潜在需求,更易演进,是大型复杂系统的推荐方法。
6.5 设计流程
-
需求分析
- 构建数据字典、数据流图(DFD)或 UML,用于梳理处理逻辑与数据来源。
- 解决命名冲突:同名异义、同义不同名、域差异等。
- 规范编码方式,确保每份信息拥有唯一责任实体。
-
概念设计
- 基于数据字典与流程识别实体、属性、关系。
- 绘制 ER 图,迭代与业务确认。
-
逻辑设计
- 将 ER 模式映射到目标 DBMS 表与视图。
- 命名规范、定义数据类型与域、确定主外键、适度反规范化、规划接口/遗留表。
-
物理设计
- 依据访问模式创建索引(单列、多列、聚簇)、分区等。
- 规划存储过程、触发器、完整性约束。
-
实现与迭代
- 建库、加载数据、制定备份与优化策略。
- 在结构规范化、冗余控制与性能之间做平衡;必要时为性能进行受控反规范化。
6.6 范式示例回顾
1NF 示例
| StudentID | StudentName | Courses |
|---|---|---|
| 1 | 张三 | 数学,物理,化学 |
→ 拆分为多行后满足 1NF:每条记录仅含一个课程。
2NF 示例
OrderDetails(OrderID, ProductID, ProductName, Quantity, CustomerName) 中 CustomerName 仅依赖 OrderID,属于部分依赖。拆分为 Orders、Products、OrderDetails 后消除冗余。
3NF 示例
Employees(EmployeeID, EmployeeName, DepartmentID, DepartmentName, DepartmentManager) 存在 DepartmentManager 对 DepartmentID 的依赖。划分为 Departments 与 Employees,可避免传递依赖导致的重复。
6.7 实践要点
- 规范化是基础,但需结合性能、用途、存储成本进行折中。
- 识别本质上相同的信息项并合并模式;同时区分确有差异的实体(如本科生/研究生)。
- 关注索引、文件结构与查询优化路径,贯穿设计全流程。
- 配合完整性约束、存储过程、触发器以及安全策略,构建全面的数据库设计方案。