什么是设计范式
设计范式是数据库设计表的依据,满足三范式的数据表可以尽可能避免数据冗余。
注:在实际的开发中,以
满足客户的需求为主,有的时候会拿冗余换执行速度。
第一范式(1NF)
数据库表中不能出现重复记录,任何一张表都应该有主键,并且每一个字段原子性不可再分。
不符合第一范式的示例:
| 学生编号 | 学生姓名 | 联系方式 |
|---|---|---|
| 1001 | 张三 | zs@gmail.com,1359999999 |
| 1002 | 李四 | ls@gmail.com,13699999999 |
| 1001 | 王五 | ww@163.net,13488888888 |
存在问题:
- 最后一条记录和第一条重复(不唯一,没有主键)
- 联系方式字段可以再分,不是原子性的
符合第一范式的数据表:
| 学生编号(pk) | 学生姓名 | 联系电话 | |
|---|---|---|---|
| 1001 | 张三 | zs@gmail.com | 1359999999 |
| 1002 | 李四 | ls@gmail.com | 13699999999 |
| 1003 | 王五 | ww@163.net | 13488888888 |
注意:
- 关于第一范式,每一行必须唯一,也就是每个表必须有主键,这是我们数据库设计的最基本要求,主要通常采用数值型或定长字符串表示。
- 关于列不可再分,应该根据具体的情况来决定。如联系方式,为了开发上的便利行可能就采用一个字段了。
第二范式(2NF)
第二范式是建立在第一范式基础上的,另外要求所有非主键字段完全依赖主键,不能产生部分依赖。
口诀:多对多?三张表,关系表两个外键。
示例:
| 学生编号 | 学生姓名 | 教师编号 | 教师姓名 |
|---|---|---|---|
| 1001 | 张三 | 001 | 王老师 |
| 1002 | 李四 | 002 | 赵老师 |
| 1003 | 王五 | 001 | 王老师 |
| 1001 | 张三 | 002 | 赵老师 |
确定主键(联合主键):
| 学生编号(PK) | 教师编号(PK) | 学生姓名 | 教师姓名 |
|---|---|---|---|
| 1001 | 001 | 张三 | 王老师 |
| 1002 | 002 | 李四 | 赵老师 |
| 1003 | 001 | 王五 | 王老师 |
| 1001 | 002 | 张三 | 赵老师 |
以上虽然确定了主键,但此表会出现大量的冗余,主要涉及到的冗余字段为学生姓名和教师姓名.出现冗余的原因在于,学生姓名部分依赖了主键的一个字段学生编号,而没有依赖教师编号,而教师姓名部门依赖了主键的一个字段教师编号,这就是第二范式需要解决的部分依赖。
解决方案如下:
学生信息表
| 学生编号(PK) | 学生姓名 |
|---|---|
| 1001 | 张三 |
| 1002 | 李四 |
| 1003 | 王五 |
教师信息表
| 教师编号(PK) | 教师姓名 |
|---|---|
| 001 | 王老师 |
| 002 | 赵老师 |
教师和学生的关系表
| 学生编号(PK) fk->学生表的学生编号 | 教师编号(PK) fk->教师表的教师编号 |
|---|---|
| 1001 | 001 |
| 1002 | 002 |
| 1003 | 001 |
| 1001 | 002 |
如果一个表是单一主键,那么它就复合第二范式,部分依赖和主键有关系。以上是一种典型的“多对多”的设计。
第三范式(3NF)
建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。
口诀:一对多?两张表,多的表加外键。
| 学生编号(PK) | 学生姓名 | 班级编号 | 班级名称 |
|---|---|---|---|
| 1001 | 张三 | 01 | 一年一班 |
| 1002 | 李四 | 02 | 一年二班 |
| 1003 | 王五 | 03 | 一年三班 |
| 1004 | 赵六 | 03 | 一年三班 |
从上表可以看出,班级名称字段存在冗余,因为班级名称字段没有直接依赖于主键,班级名称字段依赖于班级编号,班级编号依赖于学生编号,那么这就是传递依赖
解决的办法是将冗余字段单独拿出来建立表,如:
学生信息表
| 学生编号(PK) | 学生姓名 | 班级编号(FK) |
|---|---|---|
| 1001 | 张三 | 01 |
| 1002 | 李四 | 02 |
| 1003 | 王五 | 03 |
| 1004 | 赵六 | 03 |
班级信息表
| 班级编号(PK) | 班级名称 |
|---|---|
| 01 | 一年一班 |
| 02 | 一年二班 |
| 03 | 一年三班 |
以上设计是一种典型的一对多的设计:“一”存储在一张表中,“多”存储在一张表中,在“多”的那张表中添加外键指向“一”的一方的主键。
一对一的设计方案
主键共享
t_user_login 用户登录表
| id(pk) | username | password |
|---|---|---|
| 1 | zs | 123 |
| 2 | ls | 456 |
t_user_detail 用户详细信息表
| id(pk+fk) | realname | tel |
|---|---|---|
| 1 | 张三 | 1111111111 |
| 2 | 李四 | 1111415621 |
外键唯一
t_user_login 用户登录表
| id(pk) | username | password |
|---|---|---|
| 1 | zs | 123 |
| 2 | ls | 456 |
t_user_detail 用户详细信息表
| id(pk) | realname | tel | userid(fk -> id + unique) |
|---|---|---|---|
| 1 | 张三 | 1111111111 | 1 |
| 2 | 李四 | 1111415621 | 2 |
&spm=1001.2101.3001.5002&articleId=130466015&d=1&t=3&u=ad1cfd85b7df49629295e8d7b82ef122)
672

被折叠的 条评论
为什么被折叠?



