按:数据库的范式设计是为了优化关系数据库的关系模式,便于减少数据冗余以及冲突。 而范式是建立在函数依赖的基础上的。 要看懂这个还有一个基础是要明白主码,主属性和非主属性的概念。 不同阶段的范式是一个不断的优化关系模式的过程,其实就是限制条件不断升级,关系模式不断精化的过程。 不过随着范式的提高,关系模式的数量也会增加(对于个别表精化了,被剔除的关系只能形成新的关系模式),如果多个关系之间进行连接或并的操作的话,对数据库的性能会产生影响。 综合考虑一般精化至3NF即可。 高阶段的范式是在低阶段范式的基础上,加入新的限制条件形成的。所以满足高范式的一定满足比其低的范式。 第一范式是确定模式是符合关系关系模式的要求,即确立某关系属于关系模式。 第二范式是消除了非主属性对主码的部分函数依赖。 第三范式是消除了非主属性的传递函数依赖。 *3NF去除了非主属性对主键的部分函数依赖和传递函数依赖* BCNF是消除了所有属性的传递函数依赖。 *BC范式既检查非主属性,又检查主属性。当只检查非主属性时,就成了第三范式。满足BC范式的关系都必然满足第三范式* 第四范式取消了多值依赖。 第五范式取消了连接依赖。 *严格的说上述两种依赖,不属于函数依赖的范畴,可以自己参考相关书籍理解* 由于现在没有时间深入说,就把之间的关系说清就好了,反正也不难理解,再看看书就明白了^_^ 文中的例子是汇总于网络文章的,谢谢原作者了。 函数依赖 部分函数依赖------- 完全函数依赖:在一个关系中,若某个非主属性数据项依赖于全部关键字称之为完全函数依赖。 如果非主属性B函数依赖于构成某个候选关键字的一组主属性A,而不函数依赖于A的任何一个真子集,则称B完全函数依赖于A;反之,则称B部分函数依赖于A。 传递函数依赖----------- 非平凡依赖----------- 在关系模式R(U)中,对于U的子集X和Y, 如果X→Y,但Y ? X,则称X→Y是非平凡的函数依赖 若X→Y,但Y ? X, 则称X→Y是平凡的函数依赖 例:在关系SC(Sno, Cno, Grade)中, 非平凡函数依赖: (Sno, Cno) → Grade 平凡函数依赖: (Sno, Cno) → Sno (Sno, Cno) → Cno 多值依赖 见下“范式”部分,针对第四范式,第四范式就是为了取消多值依赖 连接依赖 见下“范式”部分,针对的是第五范式 ---------------------------------------------------------------------------- 首先要明白,范式的包含关系。一个数据库设计如果符合第二范式,一定也符合第一范式。如果符合第三范式,一定也符合第二范式… 范式 --------------------------------------------------------------------------- 第一范式 定义:如果关系R 中所有属性的值域都是单纯域,那么关系模式R是第一范式的 那么符合第一模式的特点就有 1)有主关键字 2)主键不能为空, 3)主键不能重复, 4)字段不可以再分 例如: StudyNo | Name | Sex | Contact 20040901 john Male Email:[email protected],phone:222456 20040901 mary famale email:[email protected] phone:123455 以上的表就不符合,第一范式:主键重复(实际中数据库不允许重复的),而且Contact字段可以再分 所以变更为正确的是 StudyNo | Name | Sex | Email | Phone 20040901 john Male [email protected] 222456 20040902 mary famale [email protected] 123455 这两种情况都不满足第一范式。不满足第一范式的数据库,不是关系数据库!所以,我们在任何关系数据库管理系统中,做不出这样的“表”来。 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。例如,对于图3-2 中的员工信息表,不能将员工信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表中只出现一次。简而言之,第一范式就是无重复的列。 ------------------------------------------------------------------------------------------ 第二范式: 定义:如果关系模式R是第一范式的,而且关系中每一个非主属性不部分依赖于主键,称R是第二范式的。 所以第二范式的主要任务就是 满足第一范式的前提下,消除部分函数依赖。 StudyNo | Name | Sex | Email | Phone | ClassNo | ClassAddress 01 john Male [email protected] 222456 200401 A楼2 01 mary famale [email protected] 123455 200402 A楼3 这个表完全满足于第一范式, 主键由StudyNo和ClassNo组成,这样才能定位到指定行 但是,ClassAddress部分依赖于关键字(ClassNo-〉ClassAddress), 所以要变为两个表 表一 StudyNo | Name | Sex | Email | Phone | ClassNo 01 john Male [email protected] 222456 200401 01 mary famale [email protected] 123455 200402 表二 ClassNo | ClassAddress 200401 A楼2 200402 A楼3 (学生上课表) 学生 课程 老师 老师职称 教材 教室 上课时间 小明 一年级语文(上) 大宝 副教授 《小学语文1》 101 14:30 一个学生上一门课,一定在特定某个教室。所以有(学生,课程)->教室 一个学生上一门课,一定是特定某个老师教。所以有(学生,课程)->老师 一个学生上一门课,他老师的职称可以确定。所以有(学生,课程)->老师职称 一个学生上一门课,一定是特定某个教材。所以有(学生,课程)->教材 一个学生上一门课,一定在特定时间。所以有(学生,课程)->上课时间 因此(学生,课程)是一个码。 然而,一个课程,一定指定了某个教材,一年级语文肯定用的是《小学语文1》,那么就有课程->教材。(学生,课程)是个码,课程却决定了教材,这就叫做不完全依赖,或者说部分依赖。出现这样的情况,就不满足第二范式! 有什么不好吗?你可以想想: 1、 校长要新增加一门课程叫“微积分”,教材是《大学数学》,怎么办?学生还没选课,而学生又是主属性,主属性不能空,课程怎么记录呢,教材记到哪呢? ……郁闷了吧?(插入异常) 2、 下学期没学生学一年级语文(上)了,学一年级语文(下)去了,那么表中将不存在一年级语文(上),也就没了《小学语文1》。这时候,校长问:一年级语文(上)用的什么教材啊?……郁闷了吧?(删除异常) 3、 校长说:一年级语文(上)换教材,换成《大学语文》。有10000个学生选了这么课,改动好大啊!改累死了……郁闷了吧?(修改异常) 那应该怎么解决呢?投影分解,将一个表分解成两个或若干个表 学生 课程 老师 老师职称 教室 课时间 小明 一年级语文(上) 大宝 副教授 101 14:30 学生上课表新 课程 教材 一年级语文(上) 《小学语文1》 课程的表 第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体 -------------------------------------------------------------------------------- 第三范式: 满足第二范式的前提下,消除传递依赖。 例: StudyNo | Name | Sex | Email | bounsLevel | bouns 20040901 john Male [email protected] 优秀 $1000 20040902 mary famale [email protected] 良 $600 这个完全满足了第二范式,但是bounsLevel和bouns存在传递依赖 更改为: StudyNo | Name | Sex | Email 20040901 john Male [email protected] 20040902 mary famale [email protected] bounsLevel | bouns 优秀 $1000 良 $600 上面的“学生上课表新”符合2NF,可以这样验证:两个主属性单独使用,不用确定其它四个非主属性的任何一个。但是它有传递依赖! 在哪呢?问题就出在“老师”和“老师职称”这里。一个老师一定能确定一个老师职称。 有什么问题吗?想想: 1、 老师升级了,变教授了,要改数据库,表中有N条,改了N次……(修改异常) 2、 没人选这个老师的课了,老师的职称也没了记录……(删除异常) 3、 新来一个老师,还没分配教什么课,他的职称记到哪?……(插入异常) 那应该怎么解决呢?和上面一样,投影分解: 学生 课程 老师 教室 上课时间 小明 一年级语文(上) 大宝 101 14:30 老师 老师职称 大宝 副教授 ---------------------------------------------------------------------- BC范式(BCNF):符合3NF,并且,主属性不依赖于主属性 若关系模式属于第一范式,且每个属性都不传递依赖于键码,则R属于BC范式。 通常BC范式的条件有多种等价的表述:每个非平凡依赖的左边必须包含键码;每个决定因素必须包含键码。 BC范式既检查非主属性,又检查主属性。当只检查非主属性时,就成了第三范式。满足BC范式的关系都必然满足第三范式。 还可以这么说:若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性,则该关系自然达到BC范式。 3NF去除了非主属性对主键的部分函数依赖和传递函数依赖。一般满足3NF的关系模式已能消除冗余和各种异常现象,获得较满意的效果,但无论2NF还是3NF都没有涉及主属性间的函数依赖,所以有时仍会引起一些问题。由此我们引入BC范式(BCNF,Boyeet和Codd提出),通常认为BCNF是第三范式的改进。 BC范式的定义:如果关系模式R∈1NF,且R中每一个决定因素都是候选键,则R是满足BC范式的关系,记作R∈BCNF。 当一个关系模式R∈BCNF,则在函数依赖范畴里,已实现了分离,消除了插入、删除的异常。 ---------------------------------------------------------------------- 第四范式: 主要任务:满足第三范式的前提下,消除多值依赖 product | agent | factory Car A1 F1 Bus A1 F2 Car A2 F2 在这里,Car的定位,必须由 agent 和 Factory才能得到(所以主键由agent和factory组成),可以通过 product依赖了agent和factory两个属性 所以正确的是 表1 表2: product | agent factory | product Car A1 F1 Car Bus A1 F2 Car Car A2 F2 Bus 第四范式是BC范式的推广,是针对有多值依赖的关系模式所定义的规范化形式。 定义:关系模式R∈1NF,X、Y是U的非空子集, ,Z=U-X-Y也非空。此时若X→→Y,则X必包含R的主键,称R是第四范式的,记作:R∈4NF。 反例:下表表示关系R4(sbm,cz#,sccj)。 设备名(sbm) 厂站代码(czdm) 生产厂家(sccj) 引风机 101 匈牙利 引风机 101 沈阳风机厂 引风机 101 成都电力机械厂 引风机 102 沈阳风机厂 分析上表,对sbm的一个值,不论sccj取什么值,总有一组确定的cz#与之对应,所以有:sbm→→cz#,同样分析有sbm→→sccj。这说明R4不满足4NF,此种关系模式有数据冗余和修改量大等弊端。可用分解法消除不满足4NF的非平凡多值依赖。解决办法:把R4分解为R41(sbm,cz#),R42(sbm,sccj)。 ----------------------------------------------------------------- 第五范式: 定义: 如果关系模式R中的每一个连接依赖, 都是由R的候选键所蕴含, 称R是第五范式的 看到定义,就知道是要消除连接依赖,并且必须保证数据完整 例子 A | B | C a1 b1 c1 a2 b1 c2 a1 b2 c1 a2 b2 c2 如果要定位到特定行,必须三个属性都为关键字。 所以关系要变为 三个关系,分别是A 和B,B和C ,C和A 如下: 表1 表2 表3 A | B B | C C | A a1 b1 b1 c1 c1 a1 a1 b2 b1 c2 c1 a2 前面我们提高范式等级的办法是分解,把一个关系用投影来代替,这些投影一般都能通过连接得到原来的关系。但有一种关系不能无损分解成两个投影,而能分解成三个以上的投影。如下图中,关系ABC可分解成两个投影AB和BC(或AC和BC)。AB与BC在上连接得ABC2;ABC2与AC再连接得ABC3。显然关系ABC2中比关系ABC多出一元组(a2,b1,c2),称之为寄生元组。ABC2与AC连接,得关系ABC3,和原关系相同。所以关系ABC具有连接依赖JD*(A,B,C)。 数据库基础:数据库范式 定义: 如果关系模式R中的每一个连接依赖, 都是由R的候选键所蕴含, 称R是第五范式的,记作:R∈5NF 附注:范式及函数依赖部分的文字都是从网上摘抄下来的,因为没有检查,如果有不对的地方请留言,我来修改~ 看了这篇文字,对数据库范式应该就会有比较全面的了解了,欢迎留言讨论 此外,对于第四和第五范式,由于涉及到的两个依赖严格来说不属于函数依赖也比较难理解,可以参考其他书。不过这两个范式用的比较少,看不懂对实际工作影响也不是很大了。 |