1 简介 范式理论是Codd研究并用来进行数据建模的方法,实践证明它适用于单个关系的微观分析,宏观分析还是使用后来推出的ER方法为好。事实上,ER分析的强项也只是在于宏观分析,有时仅仅利用ER方法并不能保证结果一定有效。 回忆以前的合同例子,有两种分析做法,一种是归纳出合同和货物两个实体,另外一种是归纳出合同、货物和厂商三个实体。前一种方案利用的准则是只要属性对于某个实体的一个实例而言是唯一的,就归入那个实体。后一种方案利用的准则是认为属性只要具有独立存在的意义和可能,就可以新建实体来表达。直接从方案来看,似乎第二种方案的实体更多而显得麻烦,但是从最终生成的关系模型来看,并非如此。如: 合同(合同号,订货日期,厂商名称,厂商地址) 只要厂商名称一样,厂商地址一定一样,存在一定的冗余。而第二种方案就没有此类冗余,如: 合同(合同号,订货日期,厂商号) 厂商(厂商号,厂商名称,厂商地址)
所以实际使用中我们可以将E-R模型用来进行宏观建模,细枝末节的东西交给范式分析解决(经过范式分析过滤一遍得到最终的合理的表结构)
应用数据库范式可以带来许多好处,但是最重要的好处归结为三点:
1.减少数据冗余(这是最主要的好处,其他好处都是由此而附带的)
2.消除异常(插入异常,更新异常,删除异常)
3.让数据组织的更加和谐…
范式分析就适合解决此类问题。在ER宏观分析基础之上,利用范式分析最终能够得到最优并且没有冗余的关系模型(说白了范式分析就是解决关系模型中数据冗余问题的)。
2 基本概念 这些基本概念是整个范式分析理论的基础内容。
2.1 函数依赖(Functional Dependency) 在关系中,常常存在一种决定和被决定的依赖关系,如非主属性对主属性的依赖关系。作为对应现实世界实体的关系而言,一个关系应该代表一个完整的概念,所以非主属性依赖于主属性是一件基本的要求。 之所以叫做函数依赖,是因为这种依赖关系非常象函数中因变量依赖自变量的关系。
2.2 平凡函数依赖与非平凡函数依赖 属性自己决定自己的依赖关系被称为平凡函数依赖,显然意义不大,所以通常情况下所说的函数依赖都是指非平凡函数依赖。所谓非平凡函数依赖是指一个属性决定其他属性的依赖关系。
2.3 完全函数依赖与部分函数依赖 考察下面的关系: (学号,所在系,系主任名称,课程名,成绩)
学号 所在系 系主任名称 课程名 成绩
000001 计算机 钱老师 Java 89
000001 计算机 钱老师 数据库 70
000002 信息 李老师 数据库 81
000003 信息 李老师 信息检索 90
说明: 一个系有若干学生, 一个学生只属于一个系; 一个系只有一名主任; 一个学生可以选修多门课程, 每门课程有若干学生选修; 每个学生所学的每门课程都有一个成绩。
关系的主键为(学号,课程名),非主属性中只有成绩属性是完全受主键决定的,这种依赖就属于完全函数依赖。而系别表面上受主键决定,但其实只受学号决定,这种依赖就属于部分函数依赖。
2.4 传递函数依赖 仍然考察上述关系,其中的系主任名表面上受主键决定,但其实只受所在系决定,而学号决定所在系,所以这种依赖就属于传递函数依赖。
不论是部分函数依赖还是传递函数依赖,都表现为破坏关系中的内在一致性,事实上,上述数据中系别和系主任名是明显具有冗余的属性,而它们都具有非完全依赖的特点。
3 范式的使用 范式(Normal Form)就是规范的形式之意。按照达到的规范程度,可以得到不同的范式级别,如同身体体质达标一样,有不同的标准形成不同的级别。没有达到范式要求的关系被称为范式违例。
3.1 2NF和3NF 2NF就是消除了部分函数依赖的范式,3NF就是消除了传递函数依赖的范式。 消除这些非完全依赖的方法都是一样的,利用拆的方法将现有关系分解为一个个独立而又完整的子关系,以实现完全依赖化。 具体步骤为: 1)找出主键属性组。 2)找出所有的依赖,即包含完全函数依赖,也包含部分函数依赖和传递函数依赖。
如关系:(学号,所在系,课程名,成绩)
学号 所在系 课程名 成绩
000001 计算机 Java 89
000001 计算机 数据库 70
000002 信息 数据库 81
000003 信息 信息检索 90
主键属性组为:学号,课程名 完全函数依赖为:学号,课程名-〉成绩 部分函数依赖为:学号-〉所在系 上述做法已经形成拆开的关系: (学号,课程名,成绩) (学号,所在系) 上述做法消除了部分函数依赖形成2NF。
所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。
再如关系:(学号,所在系,系主任名称)
学号 所在系 系主任名称
000001 计算机 程老师
000001 计算机 程老师
000002 信息 丁老师
000003 信息 丁老师
主键属性组为:学号 完全函数依赖为:学号-〉所在系 传递函数依赖为:所在系-〉系主任名称 上述做法已经形成拆开的关系: (学号,所在系) (所在系,系主任名称) 上述做法消除了传递函数依赖形成3NF。
3.2 BCNF 不论是2NF还是3NF,都可以纳入BCNF范畴之内。 BCNF是Boyce和Codd提出的一种涵盖面更广的范式概念。达到BCNF的标准为:任何非平凡函数依赖的左边必须包含键码。从概念上看,上述部分函数依赖和传递函数依赖都不满足BCNF的要求,如果存在部分函数依赖或者传递函数依赖那么必然存在某个依赖的左边不完全包含键码。所以2NF违例和3NF违例一定不是BCNF,BCNF一定是2NF和3NF(逆否定理)。上述规范化做法都是BCNF的解决做法。
3.3 4NF 上述依赖都属于函数依赖的范畴。函数依赖是属于数据依赖的一个种类,除此以外,数据依赖还包含多值依赖。而BCNF只能做到在函数依赖范围内的最高程度分解,如遇到多值依赖无法解决,如同再好的抗病毒药也不能解决基因产生的疾病。 如下面的影星信息表明显存在冗余:
影星名称 所在街道 所在城市 电影名称 拍摄年代
成龙 123号 香港 城市猎人 1990
成龙 456号 上海 城市猎人 1990
成龙 123号 香港 醉拳 1988
成龙 456号 上海 醉拳 1988
成龙 123号 香港 我是谁 1995
成龙 456号 上海 我是谁 1995
上述冗余产生的原因在于查询的要求,如下面的表格虽然简单,但是没法满足这样的查询“住在香港的影星拍过哪些电影?”
影星名称 所在街道 所在城市 电影名称 拍摄年代
成龙 123号 香港 城市猎人 1990
成龙 123号 香港 醉拳 1988
成龙 456号 上海 我是谁 1995
但是,从BCNF的角度来分析,没有问题,因为主键属性居然包含全部的属性,所以不存在部分函数依赖和传递函数依赖等问题。 造成冗余的原因在于它具有多值依赖,关系中明显将两组没有关系的内容放在一个关系中,即影星住址和影星拍摄的电影。这也需要利用拆的方式将其规范化。 从上述问题可以看出,作为关系,如果不想出问题,应该尽量保证关系内在的一致性和完整性,主属性完全决定非主属性,而不要把许多本来不属于同一个概念的内容放入一个关系内部,那样做易产生范式违例和数据冗余。
3.4 1NF 所谓1NF是对关系模型的基本要求,即一个记录的一个字段只能有一个值。所谓一个值即是指可以将其赋予一个变量,显然多个值无法同时赋予一个变量。 任何关系模型都要满足此条件,就像空气是人生存的基本条件一样。 事实上,我们使用的关系型数据库管理系统不可能做出不满足1NF要求的记录。理解此范式的主要内容在于如