Mysql - 1设计范式
数据库设计范式
| 范式层级 | 核心要求 |
|---|---|
| 1NF | 字段原子性 |
| 2NF | 消除部分依赖(完全依赖主键) |
| 3NF | 消除传递依赖(直接依赖主键) |
| BCNF | 所有决定因素都是候选键 |
基本定义
正式定义:
- 属性(attribute): 数据库中的字段,即数据库中表的列。
- 超键(super key): 在关系中能唯⼀标识元组的属性集称为关系模式的超键
- 候选键(candidate key): 不含有多余属性的超键称为候选键
- 主键(primary key): ⽤户选作元组标识的⼀个候选键称为主键
- 主属性: 候选键中的属性称为主属性。
- 非主属性: 不属于任何候选键的属性称为非主属性。
- 外键(foreign key): 在一个表中存在的另一个表的主键称为此表的外键。
第一范式(1NF)
数据库每一列均为不可分割的基本数据项 (列要符合原子性,即表中的每个属性都不可再分)
第二范式 (2NF)
表中必须要有主见,且其他属性必须完全依赖主键 (消除部分依赖)
(非主属性必须依赖于整个主键或候选键,不能只依赖于主键或候选键的一部分属性)
针对主键是多个属性的情况,那么其他非主属性必须由这几个主键同时决定
不符合 2NF:
订单表(订单ID, 产品ID, 产品名称, 产品价格, 数量) 主键:(订单ID, 产品ID) 产品名称 只依赖 产品ID(部分依赖) 产品价格 只依赖 产品ID(部分依赖) 订单 只依赖订单 ID
所以可以拆分
符合 2NF:
订单明细表(订单ID, 产品ID, 数量) 主键:(订单ID, 产品ID)
产品表(产品ID, 产品名称, 产品价格) 主键:产品ID
第三范式 (3NF)
在满足第二范式的情况下,所有的属性都不传递依赖于主键,满足第三范式, 即必直接依赖 (消除传递依赖)
即其他属性必须由主键可决定,不能被其他非主键属性决定
员工表(员工ID, 姓名, 部门ID, 部门名称) 主键:员工ID 姓名 完全依赖 员工ID ✓ 部门ID 完全依赖 员工ID ✓ 部门名称 完全依赖 员工ID ✓(符合 2NF) 但是 部门名称 依赖 部门ID(传递依赖:员工ID → 部门ID → 部门名称)
判断流程
是否有组合主键? ├─ 无 → 只需检查 3NF(传递依赖) └─ 有 → 需检查 2NF(部分依赖)和 3NF(传递依赖)
BC范式 (BCNF)
BCNF 是比 3NF 更严格的范式,也叫做修正的第三范式或3.5NF
在 3NF 的基础上,要求:每个决定因素都必须是候选键 (任何决定者都必须是候选键)
例子:
表(A, B, C, D) 候选键1:(A, B) 候选键2:(B, C) 主键:(A, B)
函数依赖: (A, B) → C (A, B) → D (B, C) → A (B, C) → D
所有决定因素 (A, B) 和 (B, C) 都是候选键 满足 BCNF
违反 BCNF:
表(A, B, C, D) 候选键1:(A, B) 候选键2:(B, C) 主键:(A, B)
函数依赖: (A, B) → C (A, B) → D (B, C) → A (B, C) → D C → D ← 问题在这里!
C → D 中,C 不是候选键,但它决定了 D
或者
仓库管理表(仓库ID, 物品ID, 管理员ID, 数量) 函数依赖: (仓库ID, 物品ID) → 数量 (仓库ID, 物品ID) → 管理员ID 管理员ID → 仓库ID(一个管理员只负责一个仓库) 管理员ID → 仓库ID,但 管理员ID 不是候选键
