数据库范式的理解

一、概念

1.函数:明确的数学上的关系,比如:总价=单价*数量。

2.函数依赖:已经知X,则有且只有Y,与之对应。比如:已经“学号1”,则有且只有“生日1”与之对应。区别于函数:函数依赖不是数学上的关系

  X→Y:Y函数依赖于X(通俗地讲:知道X是多少,就能推导出/得知 Y 是多少)

  X!→Y:Y不函数依赖于X(通俗地讲:知道X是多少,不推导出/不能得知 Y 是多少)

3.完全函数依赖:设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。

  即:X是(A1,A2,A3)的集合,如果Y完全函数依赖于A,则:

  (A1)!→Y,    (A2)!→Y,    (A3)!→Y,

  (A1,A2)!→Y,  (A1,A3)!→Y,   (A2,A3)!→Y

4.部分函数依赖:X’,Y是关系R的两个属性集合,存在X’→Y,若X是X’的真子集,存在X→Y,则称Y部分函数依赖于X’

  即:X’是(A1,A2,A3,B)的集合,它的真子集X(A1,A2,A3),若存在X’→Y,X→Y,则称Y部分函数依赖于X’。

  通俗地讲:Y依赖于X',也依赖于“ 部分的X' ”。

  部分函数依赖与完全函数依赖的区别是:

  完全函数依赖的意思是,集合X不能再拆分了,再拆分,便不能决定Y了;集合X也不能再添加元素了,再添加元素,便变成了部分函数依赖。集合元素不能增,不能减,叫完全函数依赖。

5.传递函数依赖:设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。
 
二、范式

1.第一范式

(1)涵义:是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。

  简言之:字段不可重复,不可拆分

  其实,不可拆分,需要根据实际情况进行判定。比如,一个学生的生日,可以认为是不可拆分的字段。但是,有时却可能拆分成:年,月,日。

(2)违反第一范式的害处

  是不言而喻的。这是关系型数据库最基本的要求,否则,数据库都建立不起来。

2.第二范式

(1)涵义:非关键字段完全函数依赖于候选关健字。或者说,不存在【非关键字段部分函数依赖于候选关键字】。

  如果要创建记录学生成绩的表,将(学号、姓名、性别、课程号、课程名、学分、成绩)置于同一张表中,则违反了第二范式。

  解释如下:

  A.关键字(学号+课程号),非关键字段:姓名、性别、课程名、学分、成绩。

  B.成绩则完全函数依赖于关键字(学号+课程号),

    姓名(或性别) 是 部分函数依赖于关键字(学号+课程号)【(学号+课程号)→姓名,学号→姓名】,

    课程名(或学分) 是 部分函数依赖于关键字(学号+课程号)【(学号+课程号)→课程名,课程号→课程名】。

  C.因为存在了姓名或课程名对关键字的部分函数依赖,所以,违反了第二范式。

  通俗地讲:遵守第二范式,就是消灭部分函数依赖

(2)违反第二范式的害处  

  丢失数据

  假如只有以下三条记录,如何查询体育的学分(以上图七个字段置于同一表中为例子来说明)

  因为如果没有学生选修体育,则而无法记录体育的学分信息。违反范式二,极有可能丢失重要的数据而没有记录

学号 姓名 性别 课程号 课程名 学分 成绩
1 张三 BB 数学 2 99
2 李四 BB 数学 2 98
1 张三 AA 语文 4 97

 (3)解决办法:

  将表拆分。

  拆分成四张表:(学号、姓名、性别);(课程号、课程名);(课程号、学分);(学号、课程号、成绩)

  问:为何不是(课程号、课程名、学分)?

  答:严格意义上,学分部分函数依赖于(课程号、课程名)二合一的关键字。但是,为了避免不必要的多表查询,而且课程号与课程名,课程名与学分都是一对一的关系,所以,仍然会使用(课程号、课程名、学分)

 3.第三范式

(1)涵义:不存在非关键字段对候选关键字的传递函数依赖。  

  如果要创建记录学生的班主任的表,将(学号、姓名、性别、班级、班主任)置于同一张表中,虽然并没有违反第二范式,但却违反了第三范式的。

  解释如下:

  A.因为存在学生重名的情况(姓名并不是一对一于学号,关键字只能是学号,单字段是唯一的候选关键字时,一定不存在部分函数依赖),所以表(学号、姓名、性别、班级、班主任)并没有违反第二范式。

  B.存在传递函数依赖:班主任函数依赖于班级,班级函数依赖于学号,即 学号->班级->班主任【班级!→学号】。

  通俗地讲:遵守第三范式,就是消灭传递函数依赖

(2)违反第三范式的害处

  数据冗余  

  插入异常:一个班级没有学生时,无法插入(班级、班主任)【主属性“学号”不能为空】;

  修改异常:班级更换班主任时,有多少学生,就需要修改多少条记录;

  删除异常:删除某班所有学生时,也将丢失班级与班主任的关系。

(3)解决办法

  将表拆分

  (学号、姓名、性别、班级);(班级、班主任)

  *  符合第三范式的数据库设计,基本解决了数据冗余过大、插入异常、修改异常和删除异常的问题。但在实际使用中,往往为了性能和扩展的需求,只要做到第一范式或第二范式

4.BCNF

(1)涵义:在满足第一、二、三范式的基础上,候选关键字内部各字段之间不存在函数依赖(包括完全/部分/传递函数依赖)。

  第二范式和第三范式调整的是非关键字段与关键字的关系,消灭非关键字段对关键字的部分函数依赖和传递函数依赖。而BCNF消息灭的是关键字内部各字段之间的函数依赖关系。

  如果要创建记录仓库物品数量的表,将(仓库号、存储物品号、管理员号、数量)置于同一张表中,虽然并没有违反第二、三范式,但却违反了BCNF的。

  解释如下:

  A.非关键字段只有一个:数量,候选关键字是:A(仓库号+存储物品号);B(管理员号+存储物品号)。“数量”对A和B,既没有部分函数依赖,也没有传递函数依赖,符合第二、三范式。

  B.候选关键字内部:仓库号→管理员号;管理员号→仓库号

  通俗地讲:遵守第BCNF,就是消灭关键字内部各字段之间的函数依赖

(2)违反BCNF的害处

  数据冗余

  BCNF是对第三范式的修正,使数据库冗余度更小,不应被称为第四范式。

  插入异常:一个仓库未指定管理员时,无法插入(仓库号、存储物品号、数量)【主属性“管理员号”不能为空】;

  修改异常:仓库更换管理员时,有多少物品,就需要修改多少条记录;

  删除异常:清空仓库,也将丢失仓库与管理员的关系。

(3)解决办法

  将表拆分

  (仓库号、存储物品号、数量);(仓库号、管理员号)

   * 如果满足了BCNF,那么就不再会有任何由于函数依赖导致的异常,但是我们还可能会遇到由于多值依赖导致的异常。

5.第四范式

(1)涵义:满足BCNF,并且不包含多值依赖关系。

  多值依赖的定义:表内字段全集U,被分为三个部分:X、Y、Z,它们的关系是:Z=U-X-Y,表内所有记录以 “group by X, Z”的方式进行分组,每组内有多个不重复的Y值,它们只由X值决定而与Z值无关【即:检索(X=x0 and Z=z0)时检出的一组Y值(y0,y1,y2...yn),这组Y值只由x0决定而与z0无关;且对于 每对(x,z)来说,情况都相同】,则我们称Y多值依赖于X。

  数学定义:设R(U)是一个属性集合U上的一个关系模式,X, Y, 和Z是U的子集,并且Z=U-X-Y,多值依赖X->->Y成立当且仅当对R的任一个关系r,r在(X,Z)上的每个值对应一组Y的值,这组值仅仅决定于X值而与Z值无关。

  通俗的讲:X值决定一组Y值【Z值靠边】

  A.Y多值依赖于X时,如果每组有且只有一个Y值——其实就是Y函数依赖于X【函数依赖是多值依赖的特殊情况】,这种关键字内部的函数依赖属于BCNF要消灭的对象。

  B.Y多值依赖于X时,如果Z为空集,则称Y平凡的多值依赖于X;如果Z不为空集,称Y非平凡的多值依赖于X。

  C.Y多值依赖于X时,一定会有Z多值依赖于X(对称性,X值决定一组Y值时【Z值靠边】,X值一定也决定一组Z值【Y值靠边】)。

  如果要创建记录教师学校教学科目的表,将(教师、学校、教学科目)置于同一张表中,虽然并没有违反BCNF,但却违反了第四范式。如下:

教师(X) 学校(Z) 教学科目(Y)
张三 A学校 矿物学
张三 A学校 矿床学
张三 B校 地质学基础
李四 B学校 数据结构
李四 C学校 宇宙第一编程语言 
李四 C学校 数据结构
李四 D学校 数据结构
王五 D学校  体育 
王五 D学校 定向越野

  解释如下:

  A.表内只有三个字段,共同构成关键字;没有非关键字,符合第二、三范式;它们之间没有函数依赖关系,符合BCNF。

  B. 教师(张三)决定教学科目(矿物学、矿床学和地质学基础),但与学校(A学校、B校)无关;

    教师(李四)、教师(王五)与教师(张三)情况一样【他们决定教学科目且和学校无关】

    所有教师决定 “一组所教科目”,且均与学校无关。

  所以,对于"学校"而言,“教学科目”多值依赖于"教师",

    因学校非空,所以“教学科目”非平凡多值依赖于"教师"。

    如果所有老师决定的“一组所教科目”的数量都只有一个,就变为“教学科目”函数依赖于“教师”。

    对称性:对于"学校"而言,“教学科目”多值依赖于"教师",所以,对“教学科目”而言,“学校”多值依赖于“教师”:

      教师(张三)决定学校(A学校、B校),但与教学科目(矿物学、矿床学和地质学基础)无关;

      教师(李四)、教师(王五)与教师(张三)情况一样【他们决定学校且和教学科目无关】

      所有教师决定 “一组学校”,且均所教科目无关。

  通俗地讲:三个没有函数依赖关系的字段XYZ构成一张表,表内没有相同记录。

(2)违反第四范式的害处
  插入异常:李四决定与A学校合作,但在犹豫合作教学哪个科目,是“数据结构”,还是“宇宙第一编程语言”?

        此时,无法插入李四与A学校的任何记录【教学科目作为主属性不能为空】,李四犹豫半年,A学校财务部无法查到与李四的合作关系。

        李四因此白白丢失半年薪水,虽然他掌握了“宇宙第一编程语言”,并且最终决定教学“宇宙第一编程语言”。

  删除异常:如果李四停止与C学校合作,在违反第四范式的表中直接删除记录【红色部分】,那么,就可能因此丢失信息:李四可以教学“宇宙第一编程语言”。

       张三决定放弃教学“地质学基础”,在违反第四范式的表中直接删除记录,那么,就可能因此丢失信息:张三与B校的合作关系。

  更改异常:王五被A校高薪挖掘,改在A校教学,在违反第四范式的表中直接修改记录,需要修改多条记录(此例子为2条)。

(3)解决办法

  将表拆分

    将具有 多值依赖对称性的字段Y、Z拆开,分别与决定他们的X组成2个新表。如:(教师、学校);(教师、教学科目)

教师 学校
张三 A学校
张三 B校
李四 B学校
李四 C学校
李四 D学校
王五 D学校

 

教师 教学科目
张三 矿物学
张三 矿床学
张三 地质学基础
李四 数据结构
李四 宇宙第一编程语言
王五 体育
王五 定向越野

  第四范式结合BCNF,就会让我们得出一个关系型数据库设计的终极奥义:尽量不要用两个以上的字段组合来当主键(即三个或三个以上)。如果他们之间没关系而完全独立,那么你踩中第四范式;如果他们之间有函数依赖关系,那么你踩中BCNF。如果非要这么做(超过两个字段),请保证他们之间至少有一一对应关系,而悄咪咪遵守BCNF和第四范式。用三个或三个以上字段当主键,虽然有的时候在语义上,他们不可能产生插入、修改和删除异常,但是数据库可能没办法保证每一步都遵守语义,那是人类理解的范畴。

6.第五范式

  有大神说,第五范式处理的是无损连接问题,没啥意义,不学也罢。他还说,这个世界上,还有一种只存在于理论中的范式,叫域键范式(DKNF)。

 

  

  

posted @ 2016-10-30 01:59  误会馋  阅读(563)  评论(0编辑  收藏  举报