11、数据库设计三范式
1、什么是设计范式?
设计表的依据,按照三范式设计的表不会出现数据冗余。
2、三范式
满足三范式的目的是,减少数据冗余。
第一范式:
任何一张表都应该有主键,并且每一个字段都不能再分。
学生编号 | 学生姓名 | 联系方式 |
---|---|---|
1001 | 张三 | zs@gmail.com,1359999999 |
1002 | 李四 | ls@gmail.com,13699999999 |
1003 | 王五 | ww@163.net,13488888888 |
上表违背了第一范式:
(1)没有主键
(2)联系方式字段可以再分
解决方式:
学生编号(pk) | 学生姓名 | 联系电话 | |
---|---|---|---|
1001 | 张三 | zs@gmail.com | 1359999999 |
1002 | 李四 | ls@gmail.com | 13699999999 |
1003 | 王五 | ww@163.net | 13488888888 |
第二范式:
建立在第一范式的基础之上,所有非主键字段必须完全依赖主键,不能产生部分依赖。
学生编号(pk) | 教师编号(pk) | 学生姓名 | 教师姓名 |
---|---|---|---|
1 | 1 | 张三 | 张老师 |
1 | 2 | 张三 | 李老师 |
2 | 2 | 李四 | 李老师 |
2 | 3 | 李四 | 王老师 |
3 | 1 | 王五 | 张老师 |
3 | 3 | 王五 | 王老师 |
上表为多对多关系,并且是学生编号和教师编号形成的联合主键,并且每一列都不可再分,因此满足第一范式。但是学生姓名只依赖于学生编号,并非依赖教师编号,因此形成了部分依赖,所以不满足第二范式。
解决方法:
多对多,三张表,关系表两个外键。
t_student学生表:
sno(pk) | sname |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
t_teacher教师表:
tno(pk) | tname |
---|---|
1 | 张老师 |
2 | 李老师 |
3 | 王老师 |
t_student_t_teacher_relation 学生老师关系表:
id(pk) | sno(fk) | tno(fk) |
---|---|---|
1 | 1 | 3 |
2 | 1 | 1 |
3 | 2 | 1 |
4 | 2 | 2 |
5 | 3 | 3 |
6 | 3 | 2 |
第三范式:
建立在第二范式之上,所有非主键字段直接依赖主键,不能产生传递依赖。
学生信息表:
学生编号(pk) | 学生姓名 | 班级编号 | 班级名 |
---|---|---|---|
1001 | 张三 | 01 | 高三(1)班 |
1002 | 李四 | 01 | 高三(1)班 |
1003 | 王五 | 02 | 高三(2)班 |
1004 | 麻六 | 02 | 高三(2)班 |
上述表:
- 有主键,而且数据列不可再分,因此满足第一范式。
- 非主键列对主键是完全依赖关系,满足第二范式。
- 但是,班级名依赖于班级编号,而班级编号依赖于主键学生编号,产生了传递依赖关系,因此不满足第三范式。
解决方式:
一对多,两张表,多的表加外键。
班级表:t_class
班级编号(pk) | 班级名 |
---|---|
01 | 高三(1)班 |
02 | 高三(2)班 |
学生信息表:t_student
学生编号(pk) | 学生姓名 | 班级编号(fk) |
---|---|---|
1001 | 张三 | 01 |
1002 | 李四 | 01 |
1003 | 王五 | 02 |
1004 | 麻六 | 02 |
提醒:
在实际开发中,以满足客户的需求为主,有的时候会拿数据的冗余来换执行速度。