# 数据库设计三范式
什么是数据库设计范式?
数据库表的设计依据。
# 第一范式
要求任何一张表必须有主键,每一个字段原子性不可再分
案例:
学生编号 学生姓名 联系方式
1001 张三 zs@gmail.com,135999999
1002 李四 li@gmail.com,136999999
1003 王五 ww@gmail.com,137999999
以上表设计不满足第一范式--没有主键,联系方式可拆分
修改:
学生编号(pk) 学生姓名 邮箱 联系电话
1001 张三 zs@gmail.com 135999999
1002 李四 li@gmail.com 136999999
1003 王五 ww@gmail.com 137999999
# 第二范式
建立在第一范式基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖
案例:
学生编号 学生姓名 教师编号 教师姓名
1001 张三 001 王老师
1002 李四 002 赵老师
1002 李四 002 王老师
1001 张三 001 赵老师
以上表设计不满足第一范式--没有主键
修改:
学生编号 + 教师编号(pk) 学生姓名 教师姓名
1001 001 张三 王老师
1002 002 李四 赵老师
1002 002 李四 王老师
1001 001 张三 赵老师
学生编号和教师编号连个字段做复合主键
以上修改完之后表不满足第二范式--非主键字段,产生部分依赖(学生和教师关系产生多对多关系)
导致:数据冗余,空间浪费
修改:
学生编号 学生姓名
1001 张三
1002 李四
教师编号 教师姓名
001 王老师
002 赵老师
学生教师联合表
id(pk) 学生编号(fk) 教师编号(fk)
1 1001 001
2 1002 001
3 1001 002
4 1002 002
# 第三范式
建立在第二范式基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖
案例:
学生编号(PK) 学生姓名 班级编号 班级名称
1001 张三 01 一班
1002 李四 02 二班
1003 王五 03 三班
1004 赵六 03 四班
以上表的设计满足第一范式--有主键
以上表的设计满足第二范式--主键是单一主键,不是复合主键,没有产生部分依赖(表中学生和班级是一对多关系)
以上表不满足第三范式--传递性依赖(班级名称依赖班级编号,产生了传递依赖,不符合第三范式,产生了数据冗余)
修改:
班级表
班级编号(pk) 班级名称
01 一班
02 二班
...
学生表
学生编号(pk) 学生姓名 班级编号
1001 张三 01
...
作用:避免数据冗余,空间的浪费
# 总结
一对多:
一对多,两张表,多的表加外键
多对多:
多对多,三张表,关系表两个外键
一对一:
在一对一中,可能存在表字段太多,太庞大,需要拆分表
案例:
id login_name login_pwd real_name email
1 admin admin 张三 zs@gmail.com
修改:
登录信息表:
id login_name login_pwd
1 admin admin
用户详细信息表:
id real_name email login_id(fk+unique)
100 admin zs@gmail.com 1
在一对一拆分表时,可以使用 外键+唯一性约束 设计表
# 重点
数据库设计三范式是理论上的。
实践和理论有时候有偏差。
最终的目的都是为了满足客户的需求,有的时候会拿数据冗余换速度。因为Sql中,表和表之间的连接次数过多,效率越低(笛卡尔积)
有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的。