数据库范式的定义
在设计数据库的时候,为了设计出合理的关系型数据库,就需要遵循一些规范要求,这些规范要求被成为数据库范式。
目前,关系型数据库主要有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。一般来说,数据库满足前三个范式就可以了。
第一范式(1NF)
定义
所谓第一范式(1NF)是指在关系模型中,对域添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。
解释
第一范式是指数据库表中的每个字段都是不可分解的,即数据库表中的字段具有原子性。
例如,我们有个学生信息表,如下:
id | name | age | address |
---|---|---|---|
001 | 张三 | 26 | 山东省青岛市XX县XX镇XX村XX |
002 | 李四 | 25 | 河南省开封市XX县XX区XX |
这个表就违反了第一范式,因为表中的字段 可以重新拆分为 。
id | name | age | address_province | address_city | address_detail |
---|---|---|---|---|---|
001 | 张三 | 26 | 山东省 | 青岛市 | XX县XX镇XX村XX |
002 | 李四 | 25 | 河南省 | 开封市 | XX县XX区XX |
如上图所示的表遵循了第一范式,对学生的地址管理就方便了很多,也能提高数据库的性能。比如我们要查询青岛市的学生有谁的时候。
第二范式(2NF)
定义
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。
解释
第二范式是指在第一范式的基础上,确保表中的每一列都依赖与主键,而不能只依赖与主键(联合主键)的一部分。
例如我们有个学生选课表如下:
学生ID(student_id) | 课程名称(course_name) | 学分(credit) | 成绩(score) |
---|---|---|---|
001 | 计算机科学与技术 | 10 | 80 |
002 | 计算机科学与技术 | 10 | 59 |
001 | 软件工程 | 13 | 98 |
002 | 软件工程 | 13 | 95 |
上表中,主键为 和 组成的联合主键, 完全依赖与这个联合主键,但 只依赖于 。所以违反了第二范式,产生了字段 的数据冗余。
学生ID(student_id) | 课程ID(course_id) | 成绩(score) |
---|---|---|
001 | 001 | 80 |
002 | 001 | 59 |
001 | 002 | 98 |
002 | 002 | 95 |
课程ID(course_id) | 课程名称(course_name) | 学分(credit) |
---|---|---|
001 | 计算机科学与技术 | 10 |
002 | 软件工程 | 13 |
如上所示,将 和 拆分到单独的课程表中,在学生选课表中使用 和 构成联合主键,这样就遵循了第二范式,消除了字段冗余。
第三范式
定义
第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。
解释
第三范式其实就是要消除传递依赖,确保每个字段都与主键直接相关。
例如我们在第一个例子的学生信息表中添加几个字段,如下:
id | name | age | address | class | 班主任(class_head_teacher) |
---|---|---|---|---|---|
001 | 张三 | 26 | 山东省青岛市XX县XX镇XX村XX | 101班 | 李老师 |
002 | 李四 | 25 | 河南省开封市XX县XX区XX | 102班 | 王老师 |
003 | 王五 | 24 | 河南省开封市XX县XX区XX | 101班 | 李老师 |
其中 依赖于 字段,其余字段则依赖于 字段,出现了传递依赖,并且 产生了冗余。
id | name | age | address | class_id |
---|---|---|---|---|
001 | 张三 | 26 | 山东省青岛市XX县XX镇XX村XX | 001 |
002 | 李四 | 25 | 河南省开封市XX县XX区XX | 002 |
003 | 王五 | 24 | 河南省开封市XX县XX区XX | 001 |
id | class_name | 班主任(class_head_teacher) |
---|---|---|
001 | 101班 | 李老师 |
002 | 102班 | 王老师 |
将班级相关的内容抽取成单独的班级表,学生表中值存放 做为管理。这样就符合了第三范式,消除了冗余。
文章知识点与官方知识档案匹配,可进一步学习相关知识MySQL入门技能树设计优化反范式设计31269 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!