介绍数据库规范化
了解数据库规范化,以维护数据完整性,提高灵活性,并消除数据中的不一致性。
规范化 是雷蒙德·博伊斯和埃德加·科德在20世纪70年代提出的一种数据库优化过程。规范化过程分为多个步骤,每个步骤对应一种范式,从第一范式到第五范式,其中第五范式级别最高。
按照标准实践,每个数据库都必须经过规范化处理。
在大多数数据库中,实现到第三范式即可,且不会对功能产生负面影响。
规范化的主要目标包括:
- 保证数据完整性
- 提升数据库效率
- 提供更高效的追踪方法
- 实现更合理的数据存储
- 避免各类数据问题
数据异常
谈到避免数据问题,需要特别注意 数据异常,如果未应用范式规则,这些异常会在数据库中引发问题。常见的数据异常有三种:
- 插入异常
- 更新异常
- 删除异常
我们通过以下表格来说明这些异常。
供应商表
| 产品 | 供应商 | 类别 | 类型 |
|---|---|---|---|
| 蛋白粉 | 友好补剂公司 | 运动与健身 | 乳清蛋白、酪蛋白 |
| 茶 | 世界饮品公司 | 食品与饮料 | 红茶、绿茶 |
| 氨基酸 | 友好补剂公司 | 运动与健身 | 单一氨基酸、支链氨基酸 |
| 咖啡 | 世界饮品公司 | 食品与饮料 | 核桃风味、法式烘焙 |
插入异常
插入异常 发生在无法添加新记录,除非其他相关属性已存在的情况下。例如,一家公司想推出新产品,但尚未确定供应商。此时必须等待供应商信息录入后才能添加产品信息,而不能仅输入产品内容。
更新异常
更新异常 出现在需要在多个位置修改相同值,而不是只需在一个地方修改时。例如,当供应商名称变更(如“友好补剂公司”)时,所有包含该名称的行都必须逐一更新。
删除异常
删除异常 发生在删除某条记录时,会连带删除其他本应保留的数据。
比如,公司不再销售能量饮料,需删除该行记录。这将同时删除所有与该供应商相关的数据(即所有含有该供应商的信息)。但可能我们仍希望保留该供应商的历史信息以供追溯。
了解了数据异常及其带来的问题后,接下来进入规范化的第一步。
第一范式(1NF)
第一范式(1NF)是规范化过程的第一步,必须满足1NF条件后才能进入后续步骤。1NF的要求如下:
- 单元格中不允许包含多个值。
1NF的目标是:
- 消除重复组或重复列
- 明确每张表的主键或复合主键
下面是一个未规范化的示例表,可以看到“数量”列包含多个值:
产品表
| 产品ID | 产品名称 | 数量 |
|---|---|---|
| 1 | 乳清蛋白 | 2磅,4磅 |
| 2 | 茶 | 12包,24包 |
| 3 | 氨基酸 | 60粒,90粒 |
以下是符合1NF的版本:
符合1NF的产品表
| 产品ID | 产品名称 | 数量 |
|---|---|---|
| 1 | 乳清蛋白 | 2磅 |
| 1 | 乳清蛋白 | 4磅 |
| 2 | 茶 | 12包 |
| 2 | 茶 | 24包 |
| 3 | 氨基酸 | 60粒 |
| 3 | 氨基酸 | 90粒 |
为了进一步规范化,我们可以将数量信息单独提取为一张表,并使用“数量ID”作为主键:
数量ID为主键
| 数量ID(主键) | 数量 |
|---|---|
| 1 | 2磅 |
| 2 | 4磅 |
| 3 | 12包 |
| 4 | 24包 |
| 5 | 60粒 |
| 6 | 90粒 |
第二范式(2NF)
第二范式(2NF)是规范化过程的第二步。要达到2NF,必须先满足1NF的所有条件。2NF的要求如下:
- 必须满足1NF
2NF的目标包括:
- 移除所有不依赖于主键的非键列
- 引入外键
我们继续用类似之前的例子来演示2NF的过程。
符合2NF的产品表
| 产品ID | 产品名称 | 产品描述 | 供应商 |
|---|---|---|---|
| 1 | 乳清蛋白 | 以牛奶为基础的粉末状蛋白质,用作营养补充剂。 | 友好补剂公司 |
| 2 | 茶 | 与其它茶叶来自同一茶树,采用透气茶包包装,便于冲泡。 | 世界饮品公司 |
| 3 | 氨基酸 | 构成蛋白质的基本单位——种类多样。 | 友好补剂公司 |
重申一点:2NF的一个核心目标是移除那些不依赖于主键的非键列。这意味着,若某列与主键无直接关系,应将其移到另一张表中。
在上表中,“产品ID”是主键,“产品名称”和“产品描述”均依赖于主键。
但“供应商”列是否也依赖于“产品ID”?答案是否定的。供应商信息应由其自身的主键(如“供应商ID”)来管理。因此,应将“供应商”信息拆分到独立的表中。
产品表
| 产品ID | 产品名称 | 产品描述 |
|---|---|---|
| 1 | 乳清蛋白 | 以牛奶为基础的粉末状蛋白质,用作营养补充剂。 |
| 2 | 茶 | 与其它茶叶来自同一茶树,采用透气茶包包装,便于冲泡。 |
| 3 | 氨基酸 | 构成蛋白质的基本单位——种类多样。 |
供应商ID为主键
| 供应商ID(主键) | 供应商 |
|---|---|
| 1 | 友好补剂公司 |
| 2 | 世界饮品公司 |
现在引入外键的概念:外键通过一个共同字段连接两张表。外键不仅建立表之间的关联,还确保参照完整性,使表间关系始终保持一致,从而防止数据错误。
下图中,我们在“产品”表中添加了“供应商ID”作为外键,它指向“供应商”表中的主键。
供应商ID作为外键
| 产品ID | 产品名称 | 产品描述 | 供应商ID |
|---|---|---|---|
| 1 | 乳清蛋白 | 以牛奶为基础的粉末状蛋白质,用作营养补充剂。 | 1 |
| 2 | 茶 | 与其它茶叶来自同一茶树,采用透气茶包包装,便于冲泡。 | 2 |
| 3 | 氨基酸 | 构成蛋白质的基本单位——种类多样。 | 1 |
插入供应商ID为3的记录
| 产品ID | 产品名称 | 产品描述 | 供应商ID(外键) |
|---|---|---|---|
| 4 | 研磨咖啡 | 咖啡豆经研磨机粉碎成粉末状 | 3 |
供应商表
| 供应商ID(主键) | 供应商 |
|---|---|
| 1 | 友好补剂公司 |
| 2 | 世界饮品公司 |