数据库范式

一、基本概念


1.超键

在一个关系中,能够唯一标志一个元组的属性集合被称为超键(Super Key),超键可以由单个或多个属性构成(可以为单列键也可以为复合键)。

2.候选键

也叫候选码(Candidate Key),它是一个属性集合,由关系中一个或多个属性组成,它要满足以下条件:

  • 唯一性特性: 能够唯一地标志数据库表中的一行记录(必须为超键);
  • 最小特性:其真子集不能够唯一区别数据库表中的一行记录(也叫最小超键)。

一个关系中可以有多个候选键。考虑到主键的定义,我们也可以说候选键就是能被选为主键的属性或属性组。

2.主键

也叫主关键字,或主码(Primary Key)。如果一个关系中有多个候选键,那么可以从中选取一个候选键作为主键。在一个关系中只能有一个主键,而且主键的值不能为空。在关系表中它是可选的,主键被设置时,数据库会创建主键索引。

3.主属性与非主属性

包含在任一候选键中的属性,叫做主属性(Primary Attribute),任何不包含在候选键中的属性称为非主属性(Nonprime Attribute),也叫非码属性(Nonkey Attribute)。


针对上述提及的概念,我们以下面这个关系作为示例来讲解一下:
学生成绩表(学号,姓名,身份证号,课程名,得分)
我们可以知道:

  1. {学生,课程名}、{身份证号,课程名}都是超键,也都是候选键;
  2. {学生,课程名,姓名}是超键,但它不是候选键;
  3. “学生”、“身份证号”、“课程名” 都是主属性,“姓名”、“得分” 是非主属性

注意:上面这个表结构其实存在数据的冗余,不符合2NF


4. 函数依赖
  • 数据依赖,在计算机科学中,数据依赖是指一种状态,当程序结构导致数据引用之前处理过的数据时的状态。其中最重要的是函数依赖和多值依赖;

  • 函数依赖,设X,Y是关系R的两个属性集合,当任何时刻R中的任意两个元组中的X属性值相同时,则它们的Y属性值也相同,则称X函数决定Y,或Y函数依赖于X。比如关系学生表(学号,姓名)中,确定了学生的(学号)也就确定了学生的(姓名),所以存在(姓名)(学号)的函数依赖,表示为(学号)->(姓名)

  • 平凡函数依赖,当关系中属性集合Y是属性集合X的子集时(Y⊆X),存在函数依赖X→Y,即一组属性函数决定它的所有子集,这种函数依赖称为平凡函数依赖。比如关系学生表(学号,班级),其中(学号,班级)->(学号)(学号,班级)->(班级)都属于平凡函数依赖;

  • 非平凡函数依赖,当关系中属性集合Y不是属性集合X的子集时,存在函数依赖X→Y,则称这种函数依赖为非平凡函数依赖。比如关系学生表(学号,姓名,寝室)(学号)->(姓名,寝室)属于非平凡函数依赖;

  • 完全函数依赖,设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。比如关系学生-课程表(学号,课程,得分),由于(学号,课程)->(得分)但是(学号)-\->(得分)(课程)-\->(得分),所以(学号,课程)->(得分)是完全函数依赖;

  • 部分函数依赖,设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。比如关系学生表(学号,身份证号,班级),由于(学号,身份证号)->(班级)但是同时有(学号)->(班级)(身份证号)->(班级),所以(学号,身份证号)->(班级)是部分函数依赖;

  • 传递函数依赖,设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。比如关系学生表(学号,班级,班主任),由于(学号)->(班级)但是同时有(班级)-\->(学号)(班级)->(班主任),所以(学号)->(班主任)是传递函数依赖;

函数依赖的理解属于关系理论的范畴,所以比较复杂和枯燥,但是对于后续范式的理解会有很大的助益,可以参考例子加深理解!

二、数据库范式


关系数据库中的关系必须满足一定的要求,即满足不同的范式(Normal Form)。范式是指符合某一种级别的关系模式的集合。满足适合的范式,能够帮助降低数据库的冗余,设计合理的数据库表结构。如今,关系型数据库一共有六种范式,各类范式要求依次递增,越高的范式数据库冗余越小。一般来说,数据库只需满足第三范式(3NF)就行了。

三、第一范式(1NF)


要求数据库表中的字段都是单一属性的,即属性应该是不可再分的。这是关系型数据库的基本要求。比如说属性地址,可以继续拆分成多个属性街道门牌号…仅满足第一范式的关系会存在大量的数据冗余,而且还会带来各种异常。

四、第二范式(2NF)


在第一范式的基础上,消除非主属性对候选键的部分依赖。对于候选键只有一个属性的数据库表,其一定符合2NF。比如关系如下:

学生-课程表(学号,姓名,性别,课程名,学分)

可知存在如下函数依赖:

  1. (学号,课程名)->(姓名,性别,学分)
  2. (学号)->(姓名,性别)
  3. (课程名)->(学分)

五个属性均不可再分,满足1NF,由2,3可知存在分主属性对候选键((学号,课程名))的的部分依赖,所以上述表结构不满足2NF,我们可以改造成以下三个表来满足2NF

  1. 学生表(学号,姓名,性别)
  2. 课程表(课程号,课程名,学分)
  3. 学生-课程表(学号,课程号)

五、第三范式(3NF)


在第二范式的基础上,消除非主属性对候选键的传递依赖。比如关系如下:

学生表(学号,姓名,班级名,班主任)

可知存在如下依赖:

  1. (学号)->(姓名,班级名,班主任)
  2. (学号)->(班级名)
  3. (班级名)->(班主任)

因为主键是单列键,显然,满足2NF,又由2,3可知存在(学号)->(班主任)的传递依赖,所以不满足3NF,可以改造为如下两个表使之符合3NF

  1. 学生表(学号,姓名,班级ID)
  2. 班级表(班级ID,班级名,班主任)

六、巴斯-科德范式(BCNF)

在满足第三范式的基础上,消除主属性对于候选键的部分函数依赖传递函数依赖。这里参考了知乎里刘慰老师的回答。比如有如下关系:

仓库(仓库名,管理员,物品名,数量)(仓库指定由唯一管理员管理,管理员管理唯一仓库)

可知存在如下依赖:

  1. (仓库名,物品名)->(数量)
  2. (管理员,物品名)->(数量)
  3. (管理员)->(仓库名)
  4. (仓库名)->(管理员)

可知,这里只有一个非主属性,即“数量”,且不存在非主属性对两个候选键的部分与传递函数依赖。所以以上表关系满足3NF。但存在着主属性对两个候选键的部分函数依赖,这会导致插入异常、删除异常、修改异常的存在,比如:

  • 插入异常,不能插入一个空仓库(作为主属性的“物品名”不能为空);
  • 删除异常,删除某个仓库内所有物品后,会一并将仓库的管理员信息删除;
  • 修改异常,修改仓库的管理员信息,不得不进行批量修改,同理修改物品名、仓库名时也不得不批量修改。

可以改造如下两个表结构,使之符合BCNF:

  1. 仓库(仓库名,管理员)
  2. 仓储(仓库名,物品名,数量)

推荐同学去看一看刘慰老师的回答,他的回答说明了范式应用对于设计表结构的具体好处

七、第四范式(4NF)


在BC范式的基础上,消除属性间非平凡且非函数依赖的多值依赖,这里提到的多值依赖要与前面函数依赖的概念相区分,它们两个的概念完全不同。多值依赖表示属性间的一种依赖关系,如有属性X 、Y 、Z,对于X 的每个值,Y 有一个值集,Z有一个值集,并且Y 的值集和Z的值集彼此独立。比如如下关系:

课程表(课程名,修读该课程的学生,教授该课程的教师)

上述关系满足BCNF,且可知一个课程对应N个学生的同时对应N个教师,且学生与教师是独立的,故不满足4NF,可以改造为如下的两个表结构,使之符合4NF:

  1. 学生-课程表(课程名,修读该课程的学生)
  2. 教师-课程表(课程名,教授该课程的教师)

八、第五范式(5NF)


在第四范式的基础上,消除关系中的所有冗余5NF避免了所有的数据冗余,节省了存储空间,同时保持了数据的一致性,但是也付出了效率上的代价。实际应用中,数据库适当的冗余其实有助于提高查询的效率,减少过多的表连接操作,所以5NF的应用少之又少。为了帮助理解还是举个栗子吧:

选修课表(学生,课程,教师)(多个老师可以同时教授同一门选修课,多个学生能选修同一门选修课)

可知(学生,课程,教师)就是唯一一个候选键,所有属性都是主属性,且不满足属性间的多值依赖,故满足4NF,但是存在大量冗余,可以改造为以下三个表结构,使之符合5NF

  1. 学生-课程表(学生,课程)
  2. 课程-教师表(课程,教师)
  3. 学生-教师表(学生,教师)

九、资料参考

  1. 百度百科
  2. 知乎 – 如何理解关系型数据库的常见设计范式?
  3. BCNF范式、第四范式和第五范式
  4. 郑鲁腾,杨寸月.4NF(第四范式)在实际中的应用研究[J].软件导刊,2009,8(05):49-50.
  5. 王丽华.关系数据库范式及应用[J].内江科技,2008(07):117-118.

十、勘误表

  1. 2020/03/24 第一次编辑
  2. 2020/04/10 更改标题,标题党走起
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值