你真的会设计数据库吗?快来看看数据库设计规范!

264 阅读5分钟

数据库设计是在应用程序或者系统开发过程中不可或缺的一部分,它可以帮助开发者更好地组织数据、提高系统性能,并具有更好的可维护性。在数据库设计过程中,规范化是一个非常重要的环节,它可以有效地减少冗余数据,避免数据的不一致性,提高系统的数据处理效率。下面我们就来看看在规范化数据库结构时,我们需要考虑哪些方面。

1NF (第一范式)

第一范式 (1NF) 要求数据库表中的所有列都是不可分割的原子值(原子性),即数据库表中的每个字段只能有一个值,并且每个值都是唯一的。

例如,考虑下面的学生信息表:

| 学号 | 姓名 | 课程名称                    | 分数 |
| ---- | ---- | --------------------------- | ---- |
| 1    | 张三 | 数据库,操作系统,计算机网络 | 80   |

这个表不符合第一范式,因为课程名称字段包含了多个课程名称,违反了原子性。在规范化时,我们可以拆分该表,创建一条记录对应一门课程,表结构如下:

| 学号 | 姓名 | 课程名称    | 分数 |
| ---- | ---- | ----------- | ---- |
| 1    | 张三 | 数据库      | 80   |
| 1    | 张三 | 操作系统    | 90   |
| 1    | 张三 | 计算机网络  | 85   |

2NF (第二范式)

第二范式 (2NF) 要求数据库表中的每个非主键字段都必须完全依赖于主键,也就是说,非主键字段必须完全依赖于主键中的所有列,而不是仅仅依赖于主键中的某一列。

例如,考虑下面的订单详情表:

| 订单号 | 商品编号 | 商品名 | 单价  | 数量  |
| ------ | -------- | ------ | ----- | ----- |
| 1001   | 001      | 手机   | 1999  | 1     |
| 1001   | 002      | 电视   | 2999  | 1     |
| 1002   | 003      | 电脑   | 4999  | 1     |

在这个表中,订单号和商品编号组成了复合主键,但商品名、单价和数量都只依赖于商品编号,与订单号无关。这个表不符合第二范式。在规范化时,我们可以拆分该表,创建一个商品信息表和一个订单信息表,表结构如下:

商品信息表:

| 商品编号 | 商品名 | 单价  |
| -------- | ------ | ----- |
| 001      | 手机   | 1999  |
| 002      | 电视   | 2999  |
| 003      | 电脑   | 4999  |

订单信息表:

| 订单号 | 商品编号 | 数量 |
| ------ | -------- | ---- |
| 1001   | 001      | 1    |
| 1001   | 002      | 1    |
| 1002   | 003      | 1    |

这样可以确保商品名、单价和数量只与商品编号有关联,且避免了数据冗余。

3NF (第三范式)

第三范式 (3NF) 要求数据库表中的每个非主键字段都不能依赖于其他非主键字段,也就是说,一个非主键字段不能依赖于另一个非主键字段。

例如,考虑下面的学生信息表:

| 学号 | 姓名 | 年龄 | 性别 | 班级编号 | 班级名称   | 教师姓名 |
| ---- | ---- | ---- | ---- | -------- | ---------- | -------- |
| 001  | 张三 | 20   | 男   | 01       | 计算机科学 | 王老师   |

在这个表中,班级名称和教师姓名都不依赖于学生信息,而是依赖于班级编号。这个表不符合第三范式。在规范化时,我们可以拆分该表,创建一个学生信息表、一个班级信息表和一个教师信息表,表结构如下:

学生信息表:

| 学号 | 姓名 | 年龄 | 性别 | 班级编号 |
| ---- | ---- | ---- | ---- | -------- |
| 001  | 张三 | 20   | 男   | 01       |

班级信息表:

| 班级编号 | 班级名称   | 教师姓名 |
| -------- | ---------- | -------- |
| 01       | 计算机科学 | 王老师   |

这样可以避免数据冗余,同时确保每个非主键字段都依赖于主键字段。

BCNF (Boyce-Codd范式)

BCNF 范式是在第三范式的基础上进一步规范化的,要求每个非主键字段都依赖于整个主键,而不是只依赖于主键的一部分,也就是说,每个非主键字段都不能依赖于主键的任何一部分。

例如,考虑下面的订单详情表:

| 订单号  | 商品编号  | 商品名  | 仓库编号 | 仓库地址  | 数量 |
| ------ | -------- | ------| -------- | -------- | ---- |
| 1001   | 001      | 手机   | W001     | 北京市xxx | 1    |
| 1001   | 002      | 电视   | W002     | 上海市yyy | 1    |
| 1002   | 003      | 电脑   | W003     | 广州市zzz | 1    |

在这个表中,仓库地址依赖于仓库编号,但仓库编号只是主键的一部分。这个表不符合 BCNF 范式。在规范化时,我们可以拆分该表,得到两个表:

订单表:

| 订单号 | 商品编号   | 数量 |
| ------ | -------- | ---- |
| 1001   | 001      | 1    |
| 1001   | 002      | 1    |
| 1002   | 003      | 1    |

仓库表:

| 仓库编号   | 仓库地址  |
| -------- | --------- |
| W001     | 北京市xxx |
| W002     | 上海市yyy |
| W003     | 广州市zzz |

这样,每个表都符合 BCNF 范式,没有非主键字段依赖于主键的一部分。

需要注意,BCNF 范式通常只在特定的场景下使用,因为它过于严格,有时会导致数据冗余。此外,BCNF 范式还可能导致频繁的表连接操作,影响查询效率。在实际应用中,我们需要根据具体情况,选择适合的范式来规范化数据。