注:MySQL版本众多,本次讲述的内容以MySQL8.0.34版本为准
范式化设计
范式具体是用来干嘛的?
我们在设计关系数据库时,要遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小,简单来说就是规范数据库的设计
什么范式化设计,为什么要“反”它?
范式来自英文Normal Form,简称NF。要想设计一个好的关系,必须使关系满足一定的约束条件,此约束已经形成了规范,分成几个等级,一级比一级要求得严格。满足这些规范的数据库是简洁的、结构明晰的。
目前关系数据库有六种范式:
- 第一范式(1NF)
- 第二范式(2NF)
- 第三范式(3NF)
- 巴斯-科德范式(BCNF)
- 第四范式(4NF)
- 第五范式(5NF,又被称完美范式)
【不符合第一范式】
--商品表--
商品信息
苹果(价格:15,类型:水果)
虽然可以表达想要的信息,但是这样一个字段放在这里不好,所以我们需要遵循三大范式中的第一范式:列不可再分。将这里的信息进行一个分析和拆解,一个字段一个字段拆开,不同的字段存放不同的数据信息。这样我们就符合了第一范式。
【第一范式(1NF)】
是对属性的 原子性 的要求,要求属性具有原子性,不可再分解;
--商品表--
商品名称 | 商品价格 | 商品类型 | 商品热度 |
---|---|---|---|
苹果 | 15 | 水果 | 1000 |
香蕉 | 25 | 水果 | 1000 |
香蕉 | 49 | 水果 | 1000 |
但是第一范式出现了什么问题呢?
它重复了“商品名称:香蕉”,这样你做能区分的出来吗?
为什么我买香蕉,你花25我却需要花49。这可能就是因为排序规则不一样而已。
保证字段的原子性,一个字段有一件事。
虽然商品表这样做符合第一范式,但是它不符合第二范式。行不能唯一区分
【第二范式(2NF)】
2NF 是对记录的 唯一性 ,要求记录有惟一标识,即不存在部分依赖;
--商品表--
商品id | 商品名称 | 商品价格 | 商品类型 | 商品热度 |
---|---|---|---|---|
1 | 苹果 | 15 | 水果 | 1000 |
2 | 香蕉 | 25 | 水果 | 1000 |
3 | 香蕉 | 49 | 水果 | 1000 |
第二范式,给商品表加一个主键(商品id),这样做可以用到商品id做一个区分。
理解:讲id为2的商品和id为3的商品显然就是不同的一个东西了,既是名称、价格、类型都一样,但是id是唯一做区分的。
符合第二范式,不符合三范式
【第三范式(3NF)】
3NF 是对字段的 冗余性 ,要求任何字段不能由其他字段派生出来,它要求字段没有冗余,即不存在传递依赖;
--商品表--
商品id | 商品名称 | 商品价格 | 商品类型 | 商品热度 |
---|---|---|---|---|
1 | 苹果 | 15 | 水果 | 1000 |
2 | 香蕉 | 25 | 水果 | 1000 |
3 | 香蕉 | 49 | 水果 | 1000 |
从商品表中商品类型的数据一直不断的进行一个重复 商品名称“香蕉”、商品类型“水果”等
可能会存在问题:
-
数据冗余:有重复值;
-
更新异常:有重复的冗余信息,修改时需要同时修改多条记录,否则会出现数据不一致的情况
--商品表(主)--
商品id | 商品名称 | 商品价格 | 商品类型id |
---|---|---|---|
1 | 苹果 | 15 | 1 |
2 | 香蕉 | 25 | 1 |
3 | 香蕉 | 49 | 1 |
--商品类型表(从)--
商品类型id | 商品类型 | 商品热度 |
---|---|---|
1 | 水果 | 1000 |
分析
-
商品表(主)
- 主键:
商品Id
- 非主属性:
商品名称
,商品价格
,商品类型Id
我们可以看到:
商品名称
直接依赖于商品Id
。商品价格
直接依赖于商品Id
。商品类型Id
直接依赖于商品Id
。
因此,
商品表
中的非主属性都没有传递依赖的情况,也没有依赖于其他非主属性。 - 主键:
-
商品类型表(从)
- 主键:
商品类型Id
- 非主属性:
商品名称
,商品热度
同样,我们可以看到:
商品名称
直接依赖于商品类型Id
。商品热度
直接依赖于商品类型Id
。
所以,
商品类型表
中的非主属性也都没有传递依赖的情况,也没有依赖于其他非主属性。 - 主键:
结论
通过上述分析,我们可以得出结论,这两个表的设计已经满足了第三范式的要求。每个非主属性都直接依赖于其所在表的主键,没有出现传递依赖或者依赖于其他非主属性的情况。
这样的设计能够有效地避免数据冗余和更新异常等问题,保证数据的一致性和完整性。
总结
- 1NF:属性不可再分。
- 2NF:1NF 的基础之上,消除了非主属性对于码的部分函数依赖。
- 3NF:3NF 在 2NF 的基础之上,消除了非主属性对于码的传递函数依赖
第一范式(1NF)
非码的非平凡 | ↓ 消除非主属性对码的部分函数依赖;
第二范式(2NF)
↓ 消除非主属性对码的传递函数依赖;
第三范式(3NF)
↓ 消除主属性对码的部分和传递函数依赖;
BC范式(BCNF)
↓ 消除非平凡且非函数依赖的多值依赖;
第四范式(4NF)
↓消除不是由候选码所蕴含的连接依赖;
第五范式(5NF)
设计数据库表时,一定要灵活。没必要将所有表都拆的零碎。也没必要将所有的数据都写到一张表中,几十列反而不方便查询数据。将范式和反范式相结合才是最好的设计方式。