数据库三大范式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库三大范式相关的知识,希望对你有一定的参考价值。
文章目录
- (0)什么是数据库设计范式:
- (1)第一范式
- (2)第二范式
- (3)第三范式
今天给大家讲一讲数据库三大范式
(0)什么是数据库设计范式:
- 数据库设计范式:数据库表的设计依据。按照范式设计数据库表,可以避免表中数据的冗余,空间的浪费。
标准的讲法是这样子的:
- 第一范式:当关系模式R的所有属性都不能再分解为更基本的数据单位时,称R是满足第一范式,即属性不可分。
- 第二范式:如果关系模式R满足第一范式,并且R的所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式。
- 第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,即非主属性不传递依赖于键码。
通俗的讲法是这样子的:
- 第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。(属性不可分)
- 第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。
- 第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
(1)第一范式
最核心,最重要的范式,所有表的设计都需要满足。
假设有一张表如下:
学生编号 学生姓名 联系方式
------------------------------------------
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
该表满足第一范式
(2)第二范式
假设有一张表
学生编号 学生姓名 教师编号 教师姓名
----------------------------------------------------
1001 张三 001 王老师
1002 李四 002 赵老师
1003 王五 001 王老师
1001 张三 002 赵老师
可以看出上表满足第一范式;不满足第二范式。
原因:多对多关系!(1个学生可能有多个老师,1个老师有多个学生)
学生编号 教师编号,两个字段联合做主键,复合主键(PK: 学生编号+教师编号)
学生编号+教师编号(pk) 学生姓名 教师姓名
----------------------------------------------------
1001 001 张三 王老师
1002 002 李四 赵老师
1003 001 王五 王老师
1001 002 张三 赵老师
上表不满足第二范式:张三”依赖1001,“王老师”依赖001,显然产生了部分依赖。
修改:使用三张表来表示多对多的关系
学生表
学生编号(pk) 学生名字
------------------------------------
1001 张三
1002 李四
1003 王五
教师表
教师编号(pk) 教师姓名
--------------------------------------
001 王老师
002 赵老师
学生教师关系表
id(pk) 学生编号(fk) 教师编号(fk)
------------------------------------------------------
1 1001 001
2 1002 002
3 1003 001
4 1001 002
总结:多对多设计,三张表,关系表两个外键!
(3)第三范式
学生编号(PK) 学生姓名 班级编号 班级名称
---------------------------------------------------------
1001 张三 01 一年一班
1002 李四 02 一年二班
1003 王五 03 一年三班
1004 赵六 03 一年三班
1对多关系!(一个教室中有多个学生)
满足第一范式,有主键(学生编号)。
满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。
不满足第三范式:一年一班依赖01,01依赖1001,产生了传递依赖。
修改:
班级表:一
班级编号(pk) 班级名称
----------------------------------------
01 一年一班
02 一年二班
03 一年三班
学生表:多
学生编号(PK) 学生姓名 班级编号(fk)
-------------------------------------------
1001 张三 01
1002 李四 02
1003 王五 03
1004 赵六 03
总结: 一对多,两张表,多的表加外键!
一对一: 实际开发中,可能存在一张表字段太多,太庞大。这个时候要拆分表。
没有拆分表之前:一张表
t_user
id login_name login_pwd real_name email address........
------------------------------------------------------------------------------------------------------
1 zhangsan 123 张三 zhangsan@xxx
2 lisi 123 李四 lisi@xxx
...
这种庞大的表建议拆分为两张:
t_login 登录信息表
id(pk) login_name login_pwd
------------------------------------------
1 zhangsan 123
2 lisi 123
t_user 用户详细信息表
id(pk) real_name email address........ login_id(fk+unique)
-----------------------------------------------------------------------------------------
100 张三 zhangsan@xxx 1
200 李四 lisi@xxx 2
总结:一对一,外键唯一!
注意:数据库设计三范式是理论上的;拆成多张表,查询的时候就需要连接多张表,由于笛卡尔积,查询速度慢。
实际中以空间(数据冗余)换取时间(高速)是可行的。而且不拆开表的话,SQL语句编写也简单。
以上是关于数据库三大范式的主要内容,如果未能解决你的问题,请参考以下文章