- 什么是数据库设计范式
数据库表的设计依据。教你怎么进行数据库表的设计
- 数据库设计范式共有: 3个
第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分
第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖
声明:三范式是面试官经常问的,所以一定要熟记于心!
设计数据库表时,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费
- 第一范式
最核心,最重要的范式,所有表的设计都需要满足
必须有主键,并且没一个字段都是原子性不可再分
| 学生编号 | 学生姓名 | 联系方式 |
|---|---|---|
| 1001 | 张三 | zs@gmail.com,1359999999 |
| 1002 | 李四 | ls@gmail.com,13699999999 |
| 1001 | 王五 | ww@163.net,13488888888 |
以上是学生表,满足第一范式吗
不满足
第一:没有主键
第二:联系方式可以分为邮箱地址和电话(要求每一个字段原子性不可再分)
关于第一范式, 每一行必须唯一, 也就是每个表必须有主键, 这是我们数据库设计的最基本要求
| 学生编号 (PK) | 学生姓名 | 邮箱地址 | 联系电话 |
|---|---|---|---|
| 1001 | 张三 | zs@gmail.com | 13599999999 |
| 1002 | 李四 | ls@gmail.com | 13699999999 |
| 1003 | 王五 | ww@163.net | 13488888888 |
- 第二范式
建立在第一范式的基础之上,
要求所有非主键字段,必须完全依赖主键,不要产生部分依赖
| 学生编号 | 学生姓名 | 教师编号 | 教师姓名 |
|---|---|---|---|
| 1001 | 张三 | 001 | 王老师 |
| 1002 | 李四 | 002 | 赵老师 |
| 1003 | 王五 | 001 | 王老师 |
| 1001 | 张三 | 002 | 赵老师 |
这张表描述了学生和老师的关系:(1个学生可能有多个老师,1个老师可能有多个学生)
这是非常典型的:多对多关系!
分析以上的表是否满足第一范式?
不满足第一范式
怎么满足第一范式
| 学生编号(PK) | 教师编号(PK) | 学生姓名 | 教师姓名 |
|---|---|---|---|
| 1001 | 001 | 张三 | 王老师 |
| 1002 | 002 | 李四 | 赵老师 |
| 1003 | 001 | 王五 | 王老师 |
| 1001 | 002 | 张三 | 赵老师 |
学生编号,教师编号,两个字段联合做主键,复合主键(PK:学生编号 + 教室编号)
经过修改后,以上的表满足第一范式,但满足第二范式吗
不满嘴,”张三”依赖学生编号1001 ,”王老师”依赖教师编号001,显然产生了部分依赖。
产生部分依赖有什么缺点呢
数据冗余,空间浪费。”张三”重复了,”王老师”重复了
学生信息表
| 学生编号(PK) | 学生姓名 |
|---|---|
| 1001 | 张三 |
| 1002 | 李四 |
| 1003 | 王五 |
教师信息表
| 教师编号(PK) | 教师姓名 |
|---|---|
| 001 | 王老师 |
| 002 | 赵老师 |
教师和学生关系表
| id | 学生编号(FK) | 教师编号(FK) |
|---|---|---|
| 1 | 1001 | 001 |
| 2 | 1002 | 002 |
| 3 | 1003 | 001 |
| 4 | 1001 | 002 |
口诀:
多对多怎么设计?
多对多,三张表,关系表两个外键!!!
- 第五范式
第三范式建立在第二范式的基础之上
要求所有非主键字典必须直接依赖主键,不要产生传递依赖
| 学生编号(PK) | 学生姓名 | 班级编号 | 班级名称 |
|---|---|---|---|
| 1001 | 张三 | 01 | 一年一班 |
| 1002 | 李四 | 02 | 一年二班 |
| 1003 | 王五 | 03 | 一年三班 |
| 1004 | 赵六 | 03 | 一年三班 |
分析以上表是否满足第一范式
满足第一范式,有主键
分析以上表是否满足第二范式
满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。
分析以上表是否满足第三范式
第三范式要求:不要产生传递依赖!、
班级名称一年一班依赖班级编号01,而班级编号01依赖主键学生编号1001产生了传递依赖
不符合第三范式的要求,产生了数据的冗余
那么应该怎么设计一对多
班级表:一
| 班级编号(PK) | 班级名称 |
|---|---|
| 01 | 一年一班 |
| 02 | 一年二班 |
| 03 | 一年三班 |
学生表:多
| 学生编号(PK) | 学生姓名 | 班级编号 (FK) |
|---|---|---|
| 1001 | 张三 | 01 |
| 1002 | 李四 | 02 |
| 1003 | 王五 | 03 |
| 1004 | 赵六 | 03 |
口诀:
一对多,两张表,多的表加外键!
- 总结表的设计
一对多:
一对多,两张表,多的表加外键!
多对多:
多对多,三张表,关系表两个外键!
一对一:
一对一,外建唯一!
一对一放到一张表中不就行了吗?为啥还要拆分表?
在实际的开发中,可能存在一张表字段太多,太庞大.这个时候要拆分表
一对一怎么设计?
没拆分表之前:一张表
t_userid login_name login_pwd real_name email address---------------------------------------------------------------------------1 zhangsan 123 张三 zhangsan@123.com ……2 lisi 123 李四 lisi@123.com …………这种庞大的表建议拆分成为两张表:t_login 登录信息表id(pk) login_name login_pwd--------------------------------1 zhangsan 1232 lisi 123t_user用户详细信息表id(pk) real_name email address…… login_id(fk + unique)-----------------------------------------------------------100 张三 zhangsan@123.com …… 1200 李四 lisi@123.com …… 2
口诀:
一对一,外键唯一!
- 嘱咐
数据库设计三范式是理论上的
实践和理论有的时候有偏差
最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度
因为在SQL当中,表和表之间连接次数较多,效率较低。(笛卡尔积)
有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,并且对于开发人员来说,SQL语句的编写难度也会降低
