用实例告诉你什么是数据库范式

一、前言

  数据库范式严格来说是关系型数据库范式。范式:你可以理解为实体关系的定义规则,简单说就是用来描述/规定数据库关系中的实体规则。为什么需要范式呢?举个栗子,假设有若干学生选择一个老师教授的一门课,则实体关系模型可描述为:学生(学号,学生姓名,课程名,教师名)、课程(课程号,课程名,教师名)、教师(教师号,教师名,课程名)。这样设计当然可以,但有一个缺陷:学生属性中的“课程名”、“教师名”与课程的属性重复了,而我们完全没有必要设置多余的字段来进行数据存储,所以我们一般将学生实体改为:学生(学号,学生姓名,课程号)。

  类似这样的数据之间的重复现象是数据存储时不可避免的,这种数据之间的重复,也可以说是同一数据存储在不同数据文件中的现象我们成为数据冗余。可以说增加数据的独立性和减少数据冗余是企业范围信息资源管理和大规模信息系统获得成功的前提条件。数据冗余或者信息冗余是生产、生活所必然存在的行为,没有好与不好的总体倾向。

  为了减少数据冗余,从而设计了6种范式以描述实体属性的关系定义规则,分别为:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。满足这6种范式关系模型从前往后数据冗余越来越小。因为后一种范式均是在满足前一种范式的基础上定义的。一般数据库能满足3NF即可。下面我们通过具体的例子来学习这几种范式。

二、基本名词

  在学习范式之前,掌握相关名词是必须的:

  • 实体(entity):就是实际应用中用于数据描述的事物,一般为名词,如学生、老师、课程。
  • 属性(attribute):事物(实体)必不可少的性质。如学生有:学号、姓名、年龄等属性。
  • 字段(fields):数据项。是属性在数据库中的表示形式,即我们常说的某个表的“列”。
  • 记录(record):实体的一个案例。如学生实体中的张三、李四、王五都是一条记录。
  • (key):也称为,可以对记录进行唯一标识的属性或属性集。如学生有属性(身份证,学号,姓名,年龄),其中身份证或学号都可以唯一标识一个学生。那么学生的键就有:身份证、学号、身份证和学号。
  • 主属性:包含在键中的属性成为主属性。如身份证、学号都是主属性。其余属性称为非主属性。
  • 主键(primary key):从键中选择一个唯一的、尽量小的、非空、不可更新的最为实体的主键。比如学生的主键可以选择身份证也可以选择学号,但要保证唯一性,只能选择其一。
  • 候选键:有时候码很多,但不一定都能作为主键,有时候满足主键要求的又不止一个,这样,我们称满足主键要求的键称为候选键。
  • 外键(foreign key):对连接父表和子表(一般为多对一关系)的字表主键,在父表中成为外键。如学生(学号,姓名,课程号)和课程(课程号,课程名),其中课程号是子表课程的主键,所以在学生表中称为外键。
  • 关联表(associative table):多对多关系中两个父表的子表称为关联表。
  • 属性的依赖:函数依赖的简称,可理解为某个属性集A决定某个属性B,可记做:B依赖A或A→B。例如学号→姓名。
  • 完全依赖:某个属性集A完全决定属性B,不能部分决定。如(学号,课程号)→学生姓名是部分依赖;而(学号,课程号)→课程成绩是完全依赖,因为只有学号不知道课程号无法查某科成绩,同样,只知道课程号不知道是哪个学生也无法查询。
  • 传递依赖:属性A→属性B,属性B→属性C,则有A→C,这样的依赖关系称为传递依赖。

三、第一范式(1NF):属性原子性

  1、概念

  1NF是关系模型最基本的要求,要求实体的所有属性都是不可分割的,即每一列(字段)都具备原子性、不可分割。一般要求任何数据库关系模型都应该满足1NF,除特殊关系外。

  2、实例

  比如学生这个实体:学生(学号,姓名,年龄,联系方式)就不满足1NF。因为“联系方式”还可细分为:电话号码、qq、微信等。这种不确定或说不满足原子性的设计显然存在很大问题。此处很好理解,不再赘述。

四、第二范式(2NF):非主属性的完全依赖

  1、概念

  在满足1NF的基础上,2NF要求非主属性必须完全依赖于候选码,即两者之间不存在部分依赖。如果存在部分依赖,那么应当分离出来,以新实体表示,新实体与原实体之间是一对多的关系。

  2、实例

  在学生选课的关系模型中我们有以下信息(属性):学号,学生姓名、年龄、性别、课程名、课程学分、学科成绩、系别、系办地址、系办电话。

  假设我们将信息都放在一个表(实体)中:学生选课表(学号,课程名,学生姓名,年龄,性别,课程学分,学科成绩,系别,系办地址,系办电话)。

  这是不满足2NF的,由于存在非主属性的部分依赖,如课程名→课程学分,学号→(姓名,年龄)。这样会造成很严重的数据冗余:同一门课程由n个学生选修,"课程学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。

  所以我们要进行调整,使得非主属性完全依赖于候选码,把选课关系表SelectCourse改为如下三个表:

  学生:Student(学号,姓名,年龄,性别,系别,系办地址,系办电话);

  课程:Course(课程名称,课程学分);

  选课关系:SelectCourse(学号,课程名称,成绩)。

五、第三范式(3NF):非主属性不依赖于其他非主属性(消除传递依赖)

  1、概念

  在满足2NF的基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。

  2、实例

  我们继续看上文改进为2NF的学生选课例子:

  学生:Student(学号,姓名,年龄,性别,系别,系办地址,系办电话);

  课程:Course(课程名称,课程学分);

  选课关系:SelectCourse(学号,课程名称,成绩)。

  这是不满足3NF的,其中存在传递依赖:学号→系别→(系办地址、系办电话)。这样会存在数据冗余、更新异常、插入异常和删除异常的情况。例如有n个学生属于同一个系办,那么就会重复存储n-1次系办地址和系办电话,数据出现冗余。所以我们应当消除非主属性的传递依赖,设置新实体即可:

  学生(学号,姓名,年龄,性别);

  系(系别,系办地址,系办电话)。

六、其他范式

  一般我们设计数据库时只要满足3NF即可尽可能解决数据冗余问题。所以更高级的BCNF、4NF、5NF这里简单了解即可。

  1、BCNF

  BCNF为什么不称为第四范式呢?其实BCNF又称为修正的第三范式,所以BCNF只是在3NF的基础上略微做了修改:BCNF要求若存在对于属性或属性组A属性B,那么A必须包含码,也就是BCNF排除了任何属性的传递依赖和部分依赖。因为2NF排除的是非主属性的部分依赖,3NF排除的是非主属性的传递依赖,到了BCNF,将非主属性提升为任一属性。

  例如在学生选课关系模型中:若干学生选择一门由某个老师上的课程。

  可以看出学生与课程是多对一,学生与老师也是多对一,课程与老师是一对一。存在以下函数依赖:(学生,课程)→老师;(学生,老师)课程;老师课程。

  因此该学生选课系统满足3NF,但不满足BCNF。因为老师课程,老师是决定因素但却不包含码,不满足BCNF。可以看出,BCNF范式易出现在存在1对1的关系模型中。

  2、4NF

  4NF就是限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。

  3、5NF

   5NF又称为完美范式,是指关系模式R依赖均由R候选码所隐含

posted @ 2018-04-28 16:36  风之之  阅读(1107)  评论(0编辑  收藏  举报