数据库速通:关系数据理论(上)

187 阅读4分钟

日新计划6月更文 Day 16

  这篇文章主要讲关系数据库中数据表设计的范式,这里的内容较为理论,建议灵活运用,不要照搬。

  之前我们讨论了关系型数据库的基本操作,比如数据模式的创建与删除, 数据表的创建、修改与删除,数据的添加、修改、删除与查询。但是,当我们要为某个实际问题设计合理的数据库结构时,又该注意些什么呢?这就需要关系数据理论的知识了,

  对于一张二维表,它需要符合一个最基本的条件——每个分量都是不可再分的,这称为第一范式(1NF)。

  1. 简而言之,“表中无表”

  第一范式不需要我们特意关注,关系型数据库系统不允许创建不符合第一范式的数据表。对于只符合第一范式的表,很容易发现它具有许多为题,如:

  • 数据冗余

    如大量元组具有多个对应相同的字段

  • 更新异常

    更新数据时出现数据不一致

  • 插入异常

    欲添加新数据但由于承载该数据的数据不存在而无法插入

  • 删除异常

    删除数据时由于被删除的数据承载了其他数据导致删除这些数据

  1. 一个好的模式应当不存在更新异常、插入异常与删除异常,数据冗余尽可能少。

  关系数据库中的关系要满足一定的要求,这些不同的要求称为范式。一个低级范式的关系模式可通过模式分解转换成若干个高一级范式分关系模式的集合,这就是关系模式的规范化。

  引入 2NF 前,我们先对一些概念作出解释:

  数据依赖:数据依赖是一个关系内部属性之间的一种约束关系,主要有函数依赖(Function Dependency)与多值依赖(Multi-Valued Dependency)等。

  函数依赖:设R(U)R(U)是属性UU的关系模式,X,YUX, Y \in U,若对于R(U)R(U)中任意一个可能的关系,当X上属性值相等时在Y上的属性值一定相等,则称 X 函数确定 YY 函数依赖于 X,记作XYX \to Y

  1. 函数依赖给出了关系中字段之间的依赖/相关(不是确定)关系,比如学号与学生的姓名相关

  函数依赖分为非平凡的函数依赖(XY,Y⊈XX \to Y, Y \not\subseteq X)和平凡的函数依赖(XY,YXX \to Y, Y \subseteq X),接下来我们只讨论非平凡的函数依赖。

  1. 函数依赖的定义并未排除一个字段循环依赖自己的问题,我们用平凡函数依赖定义这种行为并将其移出讨论范围

  在R(U)R(U)中,若XYX \to Y ,且对于 XX 的任意一个真子集 XX' 都有X↛YX'\not\to Y,则称 YYXX 完全函数依赖(XFYX \stackrel{F}{\to} Y),否则为部分函数依赖(XPYX \stackrel{P}{\to} Y)。

  1. 完全函数依赖真正做到了“确定”,而不是简单的相关,如学号决定了学生姓名

  在R(U)R(U)中,若XY (Y⊈X), Y↛X, YZ, Z⊈YX \to Y\ (Y \not\subseteq X),\ Y\not\to X,\ Y \to Z,\ Z \not\subseteq Y,称 Z 对 X 传递依赖。

  对于符合第一范式的关系,若其每一个非主属性完全函数依赖于任何一个候选码,则其符合第二范式(2NF)。

  1. 第二范式确立了候选码的地位,消除了非主属性对于码的部分函数依赖,关系中的一个或一组属性(候选码)(直接或间接)决定了其他的属性且这些属性不被其他属性决定。
  2. 给我把一对多的两个关系拆了

  对于符合第一范式的关系,若不存在经属性组传递依赖码的属性,则其满足第三范式(3NF)。易知满足第三范式的关系不存在部分函数依赖于码的属性,即符合第三范式的关系一定符合第二范式。

  1. 第三范式消除了非主属性对于码的传递函数依赖
  2. 给我把一对一的两个关系也拆了

  对于符合第一范式的关系,若被非平凡函数依赖的属性组一定含有码,则其满足 BCNF。BCNF可看成对 3NF 的补充或完善,避免了非码决定属性的情况。