数据库的三大范式就是数据库表的设计依据,教你如何进行数据库表的设计。
- 第一范式:要求每一张表都有主键,每一个字段必须有原子性,不可再分。
- 第二范式:建立在第一范式的基础之上,要求所有的非主键字段完全依赖主键,不要产生部分依赖。
- 第三范式:建立在第二范式的基础之上,要求所有非主键直接依赖主键,不要产生传递依赖。
设计数据库的时候,按照以上的范式设计,可以避免数据的冗余,空间的浪费。
1、第一范式 第一范式是最核心的范式,所有表都必须满足第一范式。
例如:
| 编号 | 姓名 | 联系方式 |
|---|---|---|
| 1001 | 张三 | 123@163.om,13301234567 |
| 1002 | 李四 | 123@163.om,13301234567 |
| 1003 | 王五 | 123@163.om,13301234567 |
上面这张表就不满足第一范式,因为表中没有主键,并且联系方式可以再分为邮箱和电话。
正确的第一范式应该为:
| 编号(PK) | 姓名 | 邮箱地址 | 电话 |
|---|---|---|---|
| 1001 | 张三 | 123@163.om | 13301234567 |
| 1002 | 李四 | 123@163.om | 13301234567 |
| 1003 | 王五 | 123@163.om | 13301234567 |
建立在第一范式的基础之上,要求所有的非主键依赖必须完全依赖主键,不要产生部分依赖。
例如:
| 学生编号 | 学生姓名 | 老师编号 | 老师姓名 |
|---|---|---|---|
| 101 | 张三 | 001 | 王老师 |
| 102 | 李四 | 002 | 李老师 |
| 103 | 王五 | 001 | 王老师 |
| 104 | 田六 | 002 | 李老师 |
这个表不满足第一范式,没有主键,所以修改为学生编号和老师编号联合作为主键。
| 学生编号(PK1) | 老师编号(PK2) | 学生姓名 | 老师姓名 |
|---|---|---|---|
| 101 | 001 | 张三 | 王老师 |
| 102 | 002 | 李四 | 李老师 |
| 103 | 001 | 王五 | 王老师 |
| 104 | 002 | 田六 | 李老师 |
这个表就满足了第一范式,但是不满足第二范式,因为学生姓名依赖主键中的学生编号,老师依赖主键中的老师编号,这两个都是部分依赖,所以不满足。这样的数据库就存在数据冗余的现象,王老师和李老师都出现了多次。
这是典型的多对多的关系,一个学生对应多个老师,一个老师有多个学生。
像这样的多对多的关系,我们使用三张表来表示。
所以修改为:
学生表:
| 学生编号(PK) | 学生姓名 |
|---|---|
| 101 | 张三 |
| 102 | 李四 |
| 103 | 王五 |
| 104 | 田六 |
老师表:
| 老师编号(PK) | 老师姓名 |
|---|---|
| 001 | 王老师 |
| 002 | 李老师 |
学生和老师的关系表:
| 编号(PK) | 学生编号(FK) | 老师编号(FK) |
|---|---|---|
| 1 | 101 | 001 |
| 2 | 102 | 002 |
| 3 | 103 | 001 |
| 4 | 104 | 002 |
结论:
多对多,三张表,关系表两外键,分别是其它两张表的主键。
3、第三范式 建立在第二范式基础之上,要求所有字段必须依赖主键,不要产生传递依赖。
例如:
| 学生编号(PK) | 学生姓名 | 班级编号 | 班级 |
|---|---|---|---|
| 101 | 张三 | 001 | 一班 |
| 102 | 李四 | 002 | 二班 |
| 103 | 王五 | 001 | 一班 |
| 104 | 田六 | 002 | 二班 |
这个表满足第二范式,但是不满足第三范式,因为班级依赖班级编号,但是班级编号右依赖于学生编号。这样也存在数据冗余的情况。
这个就是典型的一对多的关系,一个班级对应多个老师。
一对多的关系,我们一般使用两张表来表示。
班级表:
| 班级编号(PK) | 班级 |
|---|---|
| 001 | 一班 |
| 002 | 二班 |
学生表:
| 学生编号(PK) | 学生姓名 | 班级编号(FK) |
|---|---|---|
| 101 | 张三 | 001 |
| 102 | 李四 | 002 |
| 103 | 王五 | 001 |
| 104 | 田六 | 002 |
结论:
一对多,两张表,多的表加一个外键。
4、总结数据库表的设计 在表中存在三种关系,一对一、一对多、多对多。
一对一:
在实际开发中,一张表的字段可能会很多,所以我们有时候需要把一张表拆分为两张表,然后两张表通过外键连接,但是外键需要有唯一性约束,不然存在问题。
例如:一张表用于用户登录,另一张表用于存放用户的个人信息。
登录表:t_login
| 编号(PK) | 登录账号 | 登录密码 |
|---|---|---|
| 1 | 001 | 123456 |
| 2 | 002 | 123456 |
用户信息表:t_user
| 编号(PK) | 姓名 | 邮箱 | 性别 | 登录编号(FK) |
|---|---|---|---|---|
| 001 | 张三 | 123@163.com | 男 | 1 |
| 002 | 李四 | 123@163.com | 女 | 2 |
注意:登陆编号这个外键必须要有unique约束。
结论:
一对一,外键唯一。
一对多:
一对多,两张表,多的有一个外键。
多对多:
多对多,三张表,关系表两个外键,这两个外键分别是另外两个表的主键。
数据库三大范式是理论上的,但是实际开发中可能和理论存在偏差,最终都是要满足客户的需求。有时候我们也会通过数据的冗余去换取速度,因为在sql中,表和表之间的连接次数越多,效率越低。



