OpenShriek

mysql 表设计三大范式

written on Tuesday, July 13, 2021

设计数据库表时,要遵循以下范式以下范式

这里的规则是按照我的理解来写的,准确的表达可以看每一个范式介绍下方第一条内容,这个内容是标准的解释:
1. 保证表中每列数据的原子性,及每列数据都是不可拆分的
2. 保证表中的数据都依赖于主键,不能出现传递依赖的关系,即 A -> B -> C -> 主键
3. 保证一个表只描述一件事情,否则这张表就是需要拆分为多个的

第一范式:

数据库表中不能出现重复记录,每一个字段都应该遵循原子性,即不可分割的,什么是不可分割的,让我们往下看:

| name   | age |  Contact                      |
------------------------------------------------
| kris   | 10  |  12345678910,criselyj@163.com |
这里就出现了一个很明显的问题,就是在 Contact 字段中出现了手机号和邮箱号,其实这个字段是可以拆分为多个字段 email, phone,所以按照上面的表格设计是不符合规范的。

如果这里按照规范来拆分表结构应该是这样的:
| name  | age |  phone        | email            |
--------------------------------------------------
| kris  | 10  |  12345678910  | criselyj@163.com |

第二范式

第二范式是建立在第一范式基础上的,另外要求所有非主键字段完全依赖主键,不能产生部分依赖
比如一张表中同时存在学生和老师,并且学生和老师是关联的,这样是不符合要求的。那么想要处理这个问题也很简单,只需要将学生和老师放到两张表中,然后给两张表建立一个中间表,使 学生编号老师编号 建立关联即可,中间表设计如下
| student_id  |  teacher_id |
-----------------------------
| 1           |  001        |

这样每次我们都可以使用这个中间表来查询学生和老师关联的数据了

第三范式

建立在第二范式基础上的,非主键字段不能传递依赖于主键字段(不要产生传递依赖)
比如一张表中同时存在学生和班级,并且存在学生编号,班级编号,班级名称,那么这个班级名称就存在了冗余,因为班级名称没有直接依赖于主键,班级名称字段依赖于班级编号,班级编号依赖于学生编号,这就是传递依赖,解决的办法就是将冗余字段单独拿出来建立表
错误表结构示范:
| student_id  |  student_name | class_id  |  class_name |
---------------------------------------------------------
| 1           |  kris         | 001       |  class1     |

接下来按照我们上面的总结来解决这个问题,其实就很简单,这里只需要拆分出一个班级表,然后将班级表的 id 与 student 进行关联

`student table`
| student_id | student_name | class_id(FK) |
--------------------------------------------
| 1          | kris         | 1            |


`class table`
| id     |  class_id | class_name |
-----------------------------------
| 1      |  001       |  class1   |

实际开发中,数据库设计尽量遵循三范式,但是还是根据实际情况进行取舍,有时可能会拿冗余换速度,最终目的是要满足我们的需求

This entry was tagged mysql, note and paradigm