数据库设计三大范式(三大基本范式)
以前建数据库只是单纯的存取数据,嵌入式设备数据量比较小,也不会去考虑数据冗余的问题。后来在一次面试过程中,我陈述完项目后,面试官问我,你的数据库结构满足第几范式啊?我瞬间就懵了,范式是啥?想想也是醉了。
数据库的这三大范式是为了处理数据冗余、构建比较严谨的数据库结构,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。
下面就来说说三大范式:
1.第一范式1NF(域的原子性)
第一范式是对域的原子性的一个要求,在数据库设计中,一般都应该满足第一范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式,不过有些关系模型中突破了第一范式的限制,这种称为非第一范式的关系模型。换句话说,是否必须满足第一范式的最低需求,主要依赖所使用的关系模型。
例如:我们建一张学生信息表。
表一
学 号 |
姓名 |
性别 |
年龄 |
学 院 |
班 级 |
地址 |
100101 |
张三 |
男 |
18 |
文史 |
1年1班 |
山东省济南市历城区花园路2号 |
100202 |
李四 |
女 |
19 |
农学院 |
1年3班 |
福建省福州市晋安区爱乡园3号 |
100303 |
王五 |
男 |
21 |
医学院 |
4年1班 |
山西省太原市小店区兴武小区3栋 |
100404 |
赵六 |
男 |
20 |
英语 |
3年2班 |
江苏省徐州市泉山区解放路21号 |
表二
学 号 |
姓名 |
性别 |
年龄 |
学 院 |
班 级 |
省份 |
市(县区) |
详细地址 |
100101 |
张三 |
男 |
18 |
文史 |
1年1班 |
山东 |
济南市 |
历城区花园路2号 |
100202 |
李四 |
女 |
19 |
农学院 |
1年3班 |
福建 |
福州市 |
晋安区爱乡园3号 |
100303 |
王五 |
男 |
21 |
医学院 |
4年1班 |
山西 |
太原市 |
小店区兴武小区3栋 |
100404 |
赵六 |
男 |
20 |
英语 |
3年2班 |
江苏 |
徐州市 |
泉山区解放路21号 |
大家可以对比一下表一和二,表二在表一的基础上,将'地址"字段拆分为"省份"、"市(县区)"、"详细地址"。如果《学生信息表》的按地区查询操作比较频繁,那么表二在很大程度上提高了用户对学生学籍所在“地区”的操作效率,不用再从“地址”字段中提取“地区”信息,因此表二的设计满足了域原子性设计,也就是满足了第一范式。
2.第二范式2NF(表中除主键外的字段都完全依赖主键)
第二范式是在第一范式基础上建立的。第二范式有两个重点:(1)表中必须有主键;(2)其他非主属性必须完全依赖主键,不能只依赖主键的一部分(主要针对联合主键而言)。
例如:学生体育选修课考试成绩表
学 号 |
课程编号 |
课程 |
代课老师 |
成绩 |
100101 |
101 |
篮球 |
张 一 |
88 |
100202 |
102 |
羽毛球 |
李 二 |
87 |
100303 |
101 |
瑜伽 |
杨 三 |
79 |
100404 |
105 |
足球 |
胡 四 |
70 |
表中,每个学生选修一门课,“学号”和“课程编号”为联合主键,“成绩”都依赖于主键,而“课程”和“代课老师”则部分依赖于“课程编号”。所以,为了符合第二范式,我们将修改表结构,如下:
表三 学生选修课成绩表
学 号 |
课程编号 |
成绩 |
100101 |
101 |
88 |
100202 |
102 |
87 |
100303 |
101 |
79 |
100404 |
105 |
70 |
表四 选修课信息表
课程编号 |
课程 |
代课老师 |
101 |
篮球 |
张 一 |
102 |
羽毛球 |
李 二 |
101 |
瑜伽 |
杨 三 |
105 |
足球 |
胡 四 |
将表中课程信息单独分离出来,符合了第二范式原则。表三中的非主属性都依赖于主键,即,“成绩”字段完全依赖于“学号”和“课程编号”组成的联合主键,符合第二范式原则。这样设计,在很大程度上减小了数据库的冗余。
3.第三范式3NF(表中除主键外的字段都完全直接依赖,不能是传递依赖)
不能是传递依赖,即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。
例如:
eg:爸爸资料表,不满足第三范式
爸爸 | 儿子 | 女儿 | 女儿的小熊 | 女儿的海绵宝宝 |
改成
爸爸信息表:
爸爸 | 儿子 | 女儿 |
女儿信息表
女儿 | 女儿的小熊 | 女儿的海绵宝宝 |