范式及其对数据库设计的指导意义.ppt_第1页
范式及其对数据库设计的指导意义.ppt_第2页
范式及其对数据库设计的指导意义.ppt_第3页
范式及其对数据库设计的指导意义.ppt_第4页
范式及其对数据库设计的指导意义.ppt_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章 范式及其对数据库设计的 指导意义,范式理论及对实践指导意义概述。 范式:1NF、2NF、3NF、BCNF、4NF、5NF 实例分析及1NF、3NF的认识误区 关系模型下的树结构表达 供应商和系名问题 范式的局限对冗余的进一步讨论 单表行间冗余 多表间冗余,2.1 范式理论及对实践指导意义概述,1)范式理论形成: 1971年,由1970年首先提出“大型共享数据库数据的关系模型”的关系数据库之父 Edgar Frank Codd相继提出了三级规范化形式1NF-3NF 1974年,E.F.Codd和Boyce共同提出BCNF 1977 Ronald Fagin提出了第四范式 以后又相继提出了5NF(Project-Join Normal Form (PJ/NF) 、DKFN(Domain/Key Normal Form)和6NF,2)各范式之间关系:1NF2NF 3NF BCNF 4NF 5NF DKNF6NF 3)规范化方法:一个属于低一级的范式的关系模式可以通过模式分解转换成属于高一级范式的关系模式,这个过程称为关系模式的规范化。,4)规范化目的:消除关系中的数据冗余,由于数据冗余引发的问题: 浪费了存储资源,并且重复的数据占用的空间随数据量的递增而递增。 由于数据的重复,为保证数据的一致性,将增加数据维护(插入、更新和删除)的代价,从而降低了系统的开发和运行效率 各种意外还是可能造成重复数据的不一致,从而降低了系统的稳定性和可靠性。 是产生插入,更新和删除异常根源(见下例),插入,更新和删除异常实例:,假设存在下列关系,包含学生和系的基本信息: 学号 姓名 所在系 系主任 001 zhang 数学 Mr Li 002 wang 数学 Mr Li 003 zhou 数学 Mr Li 004 feng 计算机 Mr chen 005 dong 计算机 Mr chen 该关系存在插入,更新和删除异常。,插入异常:当新成立一个系但还没有学生时,产生插入异常。 删除异常:当一个系的学生被全部删除后,系信息也被删除。 更新异常:当系名称或系主任发生变化,必须同时更新这个系所有学生记录,若漏改一个,就产生更新异常。,5)规范化理论对实践的指导意义,异常分类:关系设计不规范引起插入,更新和删除异常有的可以通过严密的算法避免发生,有的则不能避免。在上例中,插入和删除异常不可避免,而更新异常却可以避免。 不可避免异常:若数据库的设计中存在不可避免的异常时,需求将无法实现,设计者会自觉地消除这些异常。在上例中,一般会增加一个“系(系名,系主任)”关系来排除不可避免的插入和删除异常。这时,规范化设计成为设计师自觉的行动,可避免异常:关系规范化理论对设计者有指导意义的是消除可避免异常引起的数据冗余。 冗余和范式关系: 一般消除了一个关系中的数据冗余(除外键引用为必要的数据冗余外),该关系也就符合了范式要求。 一个关系符合范式要求,一般就不会产生数据冗余,但必须注意的是范式可以消除一个关系中的(单行)数据冗余,但不能消除一个表的行间冗余和多个关系之间的数据冗余。,2.2 范式 2.2.1 1NF及对实践的指导意义 1)定义,1NF的定义1:若关系中所有属性是不可再分的基本项(原子项),即关系中的属性不能是组合属性,称关系属于或服从第一范式。 1NF的定义2:关系模式R中不能含有任何重复的数据项。(Robert D. Schnneider 规划与建立高性能SQL Server 6.5数据库) 第一范式是关系数据模式必须遵循的规范,其他规范均建立在此基础之上。 关系的一切数学理论均基于关系模式服从1NF。,如一个学生的成绩包括数学,语文,外语等,则成绩不能作为学生关系中的一 个属性。 要使其符合1NF,必须把数学,语文,外语成绩直接作为学生关系的属性。 由于关系数据库中表中列之间的关系相互并列,本身不支持层次结构或数组,所以表面上看,只要是二维表,就一定符合1NF,2)1NF的第一层次的解释,3)1NF的第二层次的解释,不要或没有必要把若干属性或代码组合成一个组合属性或组合代码放在一个数据列中。这同样违反1NF 。 这样做的风险是数据库系统对组合属性中某属性的可操作性(子串)一定不如对列的可操作性。 解决上述问题的方法也不要简单地把组合属性分解成列,当这些属性有扩充的可能时,应单独建立一个关系。(后面有详例分析),4)1NF的第三层次的解释,1NF要求在一行中不能有重复组,不管是重复的列还是列中含有的重复信息都不允许。(数据库设计) 如不要把数学成绩,语文成绩和外语成绩作为学生关系中的属性,因为,一旦增加一门课程,该关系就必须作修改。 正确的做法是把成绩独立出来,形成的关系模型为:成绩(学号,学科号,成绩) 类似的如在学生关系中有联系电话属性,而每一个学生可能有不确定的电话数量,则增加属性“电话1”、“电话2”,同样不符合1NF要求,正确的做法是增加关系:R(学号,电话号码),2.2.2 2NF及对实践的指导意义,关系属于第一范式并且每一个非主属性完全依赖于码,则称关系属于第二范式。 由于非主属性均函数依赖于码,所以第二范式去除了非主属性对码的部分依赖。 假设(x,y)为关系R(U)的码,有非主属性z,yz,由于y不包含码,所以关系的行中y值必有重复, yz,z值与y值同步重复。 一般可以把R(U)分解成R1(U-z)和R2(y,z),使子关系均属于2NF,同时消除了冗余。,单据号 单据日期 品号 品名 数量 b001 2003-2-1 G01 A 10 b001 2003-2-1 G02 B 12 b002 2004-2-7 G02 B 20 单据号,品号为关系的主码,“单据日期”为非主属性,“单据号”“单据日期”,即非主属性“单据日期”部分依赖于码,这种设计的数据冗余显而易见。 把关系分解为:单据摘要(单据号*、单据日期)和单据明细(单据号*,品号*,品名,数量),通过单据号建立关联。,例.单据的单表设计就不属于第2范式,思考练习:,分别完成单据的两种设计下的下列操作的设计,并进行比较: 单据明细的增加,删除和修改 单据的增加和删除。 空白单据的处理,若把学生学科成绩设计成(学号,姓名,学科号,学科名,成绩),该关系就不符合第二范式。(“学号”,“学科号”)为该关系的主键(码),非主属性中,除“成绩”完全依赖于主键,“姓名”和“学科名”不完全依赖于主键,即仅分别完全依赖于主键的子集“学号”和“学科号”。 要使其符合2NF,必须把上述关系分解成三个关系:学生(学号,姓名,)、学科(学科号,学科名,)和成绩(学号, 学科号, 成绩)。,例.学生学科成绩的关系模型设计,2.2.3 3NF及对实践的指导意义,关系属于第一范式且关系中不存在非主属性Z传递函数依赖于码,则称关系属于第三范式。 在传递函数依赖XYZ的定义中隐含YX和ZY,但3NF定义中的传递函数依赖允许YX (或YX),由此才能保证2NF 3NF。 假如不放宽传递函数依赖条件,则关系:学生选课(学号,课程号,课程名)不符合2NF但符合3NF,因为我们找不到属性组Y,使唯一的非主属性“课程名”传递函数依赖于码(学号,课程号),即(学号,课程号) Y课程名。而定义条件放宽后,可取Y=“课程号”。 第三范式是在关系中去除非主属性对码的传递函数依赖。,不属于3NF必然存在冗余,X,Y,Z为关系R(U)的属性组,且X为码, XYZ,由于Y+X,所以Y必不包含码,在关系的行中Y值必有重复,而YZ,所以Z值同步重复。 一般可以把R(U)分解成R1(U-Z)和R2(Y,Z),使子关系均属于3NF,同时消除了冗余。,如在学生关系中增加所在“系”和“系主任”属性,则该关系就不符合第三范式,因为由依赖关系“学号系系主任”,中间就存在了传递函数依赖,学号系主任。 学号 姓名 系 系主任 001 wang 数学 Li 002 Feng 数学 Li 003 Cheng 数学 Li 004 Huang 物理 Xu 显然这种设计存在数据冗余,正确的做法是在学生关系中增加“系编号”属性,同时增加一个关系:系(系编号,系名,系主任) 。 学号 姓名 系号 系号 系 系主任 001 wang 01 01 数学 Li 002 Feng 01 02 物理 Xu 003 Cheng 01 004 Huang 02 单据中包含商品代码外,还包括商品属性,同样不符合第三范式,因为存在下列传递函数依赖:(单据号,单据明细序号)商品代码商品属性。,2.2.4 BCNF-扩充的第三范式,关系模式R(U,F)1NF,若XY (YX),X必包含码,则R(U,F) BCNF。 BCNF是在3NF基础上去除主属性对码的部分和传递依赖。 X,Y为关系R(U)的属性组, XY,且X不包含码,在关系的行中X值必有重复,而XY,所以Y值同步重复。 一般可以把R(U)分解成R1(U-Y)和R2(X,Y),使子关系均属于BCNF,同时消除了冗余。,属于3NF但不属于BCNF的例: 学生选课(学号,课程号,教师编号,成绩),假设一个教师只上一门课。则:教师编号课程号,但教师编号不是关系的码,所以此关系不属于BCNF。 学号 课程号 教师编号 成绩 001 数据库 Li 89 001 C语言 Zhang 76 002 数据库 Li 99 003 数据库 Li 87 显然这种设计存在数据冗余,(学号,课程号)和(学号,教师编号)均为关系的码,所以学号、课程号和教师编号为主属性,成绩为非主属性,显然,成绩不传递函数依赖于上述两个码,所以关系属于3NF。 把上述关系分解成:学生选课(学号,教师,成绩)和教师任课(教师,课程)关系就符合BCNF。 学号 教师 成绩 教师 课程 001 Li 89 Li 数据库 001 Zhang 76 Zhang C语言 002 Li 99 003 Li 87,思考和练习:,是否可以分解成:学生选课(学号,课程,成绩)和教师任课(教师,课程)?说明原因。,2.2.7 各范式关系小结,1NF基础上去除非主属性对码的部分依赖成为2NF 2NF基础上去除非主属性对码的传递依赖成为3NF 3NF基础上去除主属性对码的部分和传递依赖成为BCNF BCNF基础上去除非平凡和非函数依赖的多值依赖成为4NF 4NF基础上去除不是由侯选码蕴涵的连接依赖成为5NF 5NF4NF BCNF 3NF 2NF 1NF 低一级模式可以通过模式分解转换为高一级模式,一个商场的商品分类: 商品分类 服装 男装 西装 休闲装 女装 套装 职业装 休闲装 童装 电器 进口 国产 日用品,2.3 实例分析: 2.3.1 正确理解1NF-树结点的数据表设计:,代码(主码) 名称 01 服装 0101 男装 010101 西装 010102 休闲装 0102 女装 010201 套装 010202 职业装 010203 休闲装 0103 童装 02 电器 0201 进口 0202 国产 03 日用品,关系模型设计:,冗余分析:,在上述设计中增加“上级代码”、“代码级数”、“是否为叶结点”等列,显然,这些列的数据为冗余数据,因为这些数据值完全可以由“代码”计算得到。 这些列并不传递或部分依赖于码 似乎产生了一种既有数据冗余但又符合所有范式的模式,分析代码包含信息:“代码”属性不是原子项,它至少包含了下列两个信息(所以不符合1NF): 本级代码 上级代码, 而上级代码又包含了上述两个信息。 1NF规范化:主要任务是把代码项分解为原子项: 思考一:把代码分解成本级代码和上级代码两项,由于上级代码仍包含本级代码和上级代码,所以不是原子项。这个思路不可行 思考二:由于“代码”实际包含了一个树结构信息,参考数据结构中方法,可以把代码分解成下列原子项: id: 流水号,主键 code: 本级代码 pid: 父结点id,对上述关系模型的分析:,code name id code pid name 0 0 01 服装 1 01 0 服装 0101 男装 2 01 1 男装 010101 西装 3 01 2 西装 010102 休闲装 4 02 2 休闲装 0102 女装 5 02 1 女装 010201 套装 6 01 5 套装 010202 职业装 7 02 5 职业装 010203 休闲装 8 03 5 休闲装 0103 童装 9 03 1 童装 02 电器 10 02 0 电器 0201 进口 11 01 10 进口 0202 国产 12 02 10 国产 03 日用品 13 03 0 日用品 为以后算法实现的方便,左边设计第一行为根结点,并且code类型必须使用var char避免空格。以下假设上列数据对应两个表:classes_1和classes_2。,两种设计的比较:范式的意义,两种设计的可行性:原始设计中关系虽然不符合1NF,但此设计中代码包含了分类树的所有结构信息,所以设计方案是可行的。规范后的设计通过pid建立结点的父子关系同样包含了树的所有结构信息,所以也是可行的。 比较方法:从冗余、扩展能力及空间利用率、结点引用和各种算法四个方面进行比较,一)冗余,每一个结点只需要知道其父结点代码,就可以构建一棵树,而根据第一种设计,其每一个结点均包含了其所有祖先的结点代码,这就是冗余的信息。 设计一冗余的信息被隐藏在一个列中,并且随树结构层数的增加而增加 设计二没有冗余,二)扩展能力及空间利用率,第一种设计表示的树结点的层数受code列长度的限制,而第二种设计则没有这种限制。 为了能适应结点层数的扩展,第一种设计不得不加大code列的长度,由于code列为主码,从效率角度考虑,通常其数据类型会首先考虑使用char型,所以在实际的代码后会存在大量的空格。 在每一级代码长度不一样的情况下,第二种设计的code列同样会产生少量的空格,但由于code列不是主码,可以把其类型定义为varchar解决这个问题。,三)结点的引用,第一种设计若直接选择code列主码,则一旦代码进行修改,通过外键引用该表的关系也要做修改。 第二种设计由于其他关系通过id列引用该表,所以当code列修改后,通过外键引用该表的关系无需做修改。 作为外码,引用第二种设计的id对空间的占用比引用第一种设计code对空间占用要小。 设计一也可人为地增加一个主码,但客观上又造成新的空间占用。,四)算法比较 1) 规范化设计较非规范化设计简单的算法:,对某个结点是否为叶结点的判断 通过判断select结果是否为空,第一种设计select的where条件较复杂 获取所有叶结点 都需要使用子查询,但设计一子查询中要引用主查询中的列 获取某个结点从根结点开始的完整路径 都可以使用select获得,但设计一更复杂,2)规范化设计与非规范化设计复杂性相近的算法,结点的迁移、复制和交换 例1:把0101下的所有结点复制到0102的结点下 结点的增加、删除和修改 逐级求和的实现 例2 :逐级求和的演示,例1:把0101下的所有结点复制到0102的结点下 code name id code pid name 0 0 01 服装 1 01 0 服装 0101 男装 2 01 1 男装 010101 西装 3 01 2 西装 01010101 全毛 4 01 3 全毛 01010102 化纤 5 02 3 化纤 010102 休闲装 6 02 2 休闲装 0102 女装 7 02 1 女装 010201 套装 8 01 7 套装 010202 职业装 9 02 7 职业装 010203 休闲装 10 03 7 休闲装 010204 西装 11 04 7 西装 01020401 全毛 12 01 11 全毛 01020402 化纤 13 02 11 化纤 010205 休闲装 14 05 7 休闲装,code amt id code pid amt 0 0 01 900 1 01 0 900 0101 300 2 01 1 300 010101 100 3 01 2 100 010102 200 4 02 2 200 0102 390 5 02 1 390 010201 120 6 01 5 120 010202 130 7 02 5 130 010203 140 8 03 5 140 0103 210 9 03 1 210 02 290 10 02 0 290 0201 140 11 01 10 140 0202 150 12 02 10 150 03 300 13 03 0 300,例2:各结点包含数量的逐级求和,3)规范化设计劣于非规范化设计的算法,取某结点的所有子结点 获取结点所在层数 某级代码长度加长 获得结点在设计一中的code 注:可以在第二种设计中增加一个level列表示一个结点所在的层数,这样可以使第1到第个算法变得和非规范化设计一样简单,例3:一些算法的实现或思路,设计一:判定code=codev结点是叶结点 select * from classes_1 where code like codev+% and len(code)len(codev)为空集。 设计二:判定id=idv结点是叶结点 select * from classes_2 where pid=idv为空集。 设计一:取出所有叶结点 select * from classes_1 a where not exists (select * from classes_1 where code like rtrim(a.code)+% and len(rtrim(code)len(rtrim(a.code),设计二:取出所有叶结点 即获取id不出现在父结点集中的结点 全体父结点集的id: select pid from classes_2 where pid is not null 所有叶结点:select * from classes_2 where id not in (select pid from classes_2 where pid is not null) 设计二:获得结点路径 select isnull(,)+/+ isnull(,)+/+isnull(,) from classes_2 a,classes_2 b,classes_2 c where c.pid=b.id and b.pid=a.id 表达式中有部分值为null,则整个表达式值为null,有些DBMS会把null处理为空串。 该语句对最大级数为1,2,3均适用,若级数大于3,上述语句可作相应扩展。,设计一算法:取代码为codev结点的所有子结点 select * from classes_1 where code like codev+”%” 设计二算法:取id=idv结点的所有子结点 select * from classes_2 where pid=idv or pid in (select id from classes_2 where pid=idv),结点的迁移、复制和交换 例:把男装下所有子结点(西装和休闲装)复制到女装下 算法:扫描要复制的子结点,若是第一层子结点,依次产生新的代码,若非第一层子结点 设计一:则代码为上一层新增的代码+要复制的最后一级代码。 设计二:复制被复制代码,pid为上级代码的id,设计一:由代码总长得到代码级数 设计二:比较困难,循环搜索父结点,直到根结点,所以n级代码要对整表扫描n次后才能获得其级数n。 vlev=1;vid=当前结点id;vpid=当前结点pid; while (vpid!=0) /有父结点 整表扫描找到当前结点的父结点(id=vpid的行): vid=id;vpid=pid; vlev=vlev+1; return vlev,某级代码长度加长,基本方法是对存在的某级代码全部左补“0” 设计一:若分级代码被其他关系外键引用,除容易产生更新异常外,对代码表本身的修改简单。 设计二:关键是怎样获得所有某级别的代码,然后左补“0”,也就是本问题的解决依赖于上一问题的解决。 可以在表中增加“级数”(level)字段解决规范化设计的这一缺陷,具体设计和分析见2.4中行间冗余的例1,分级代码的还原(用到了根结点),设计一:直接取code 设计二:select isnull(a.code,)+ isnull(b.code,)+isnull(c.code,) from classes_2 a,classes_2 b,classes_2 c where c.pid=b.id and b.pid=a.id order by 1; code类型必须使用varchar避免空格,该语句对最大级数为1,2,3均适用),一般不符合范式就会有数据冗余,上例并不是例外,因为“代码”列本身存在冗余,“010101”是对“0101”的冗余,“0101”是对“01”的冗余。 不属于某个范式甚至是1NF的关系设计不一定就是一个不好的设计,但如果使它规范化,那可能是一个更好的设计。 一个看上去比较复杂的设计,并不一定会给以后的实现带来更多的复杂性。,结论:,2.3.2 3NF在实践中应用问题,一)问题提出 引用数据发生变更的处理: 例1:系名问题:学校系名变更,要求学生各时期的系名仍使用当时的系名。一个学生在就学期间可能对应多个系名。 例2:供应商问题:商品的供应商名称发生变更,要求变更前进货单中的供应商仍保留原来名称。与系名问题不同的是一个进货单只可能对应一个供应商名。 上述两种情况,若在学生关系或商品关系中仅以系编号或供应商编号引用系信息或供应商信息,符合3NF,但一旦对应信息发生变更(如供应商名称),原信息被覆盖(丢失)。,二)供应商问题的常见解决方案,方案:把可能变更的且要保留的引用数据放入引用表中,如把供应商编号和进货时的供应商名称同时存入进货单中。 分析(是否符合范式):(后者认识上有误区) 1)若不发生系供应商名称变更,则由于存在传递依赖“进货单号供应商号供应商名称”,上述设计不符合3NF。 2)误区:当供应商名称发生变更,由于进货单中存放的是进货时供应商名,所以(1)中传递依赖不再成立,所以符合3NF。 3)正确的判断:若供应商名发生变更,事实上成立传递依赖:“进货单号(供应商号,进货日期)供应商进货时名称”,所以关系仍不符合了3NF。,冗余分析:存在两个方面的冗余 对引用信息变更部分:变更前的信息重复(下例中的红色部分) 对引用信息未变更部分:若引用信息发生变更的频率极低,显然增加的列对大多数引用信息未发生变更的情况是纯粹的冗余。(下例中绿色部分),*供应商编号 供应商名称 A00011 海尔冰箱厂 A00012 长虹电器有限公司 A00013 益民食品厂 A00012原名长虹电器厂,*进货单号 供应商编号 供应商名称 D001 A00011 海尔冰箱厂 D002 A00011 海尔冰箱厂 D003 A00012 长虹电器厂 D004 A00012 长虹电器厂 D005 A00011 海尔冰箱厂 D006 A00012 长虹电器厂 D007 A00012 长虹电器有限公司,三)符合范式的解决方案,目标:使设计符合所有范式要求。 基本方法:使用供应商表和供应商名称变更表记录供应商所有曾用名。,1)方案一:,关系模型设计: 供应商(*供应商编号,供应商当前名称,) 供应商名称变更表(*供应商编号,*名称版本号,变更日期,供应商原名称) 进货单摘要(*单号,日期,供应商编号,名称版本号,) 模型设计说明: 变更表记录供应商的原名称,而新名称总是存放在供应商表中。 供应商名称变更表合理假设同一天供应商名称不会变更两次,所以可以以(日期,供应商编号)为码。但考虑到引用的便捷性,加入一个版本号(流水号,对每一个供应商从1开始,每变更一次加1)。,概要设计:,新增进货单:仅引用供应商表,名称版本号取0 供应商名称变更: (供应商信息维护的一个部分) (1)名称变更:供应商名称变更表新增一行,版本号为上一变更版本号+1 (2)更新当前供应商名称:以新供应商名称替换供应商表中供应商名称。 (3)更改进货单对供应商名称的引用:所有该供应商且供应商名称版本号=0的进货单,其供应商名称版本号取(1)中产生的版本号。 查询进货单(含供应商):若供应商名称版本号=0,则供应商名称引用供应商表,否则引用供应商名称变更表。(练习select),设计特点:,符合所有范式 若原系统设计没有考虑供应商名称变更问题,此设计对原设计影响较小。 供应商名称变更较少发生的情况下,本设计对系统的性能(查询效率)基本无影响。,2)方案二:,关系模型设计: 供应商(*供应商编号,地址,电话,) 供应商名称变更表(*供应商编号,*供应商名称版本号,名称设定日期,供应商名称) 进货单(*单号,日期,供应商编号,版本号,) 模型设计说明 供应商名称全部放在“供应商名称变更表”,概要设计:,新增进货单:仅引用供应商变更表中名称版本号最大的行。(练习select) 供应商名称变更: (包括供应商信息维护) 新增供应商或名称变更:供应商名称变更表新增一行,版本号从0开始,或为上一变更版本号+1 查询进货单(含供应商):全部通过供应商编号和名称版本号引用供应商名称变更表。,设计特点:,符合所有范式 若原系统设计没有考虑供应商名称变更问题,此设计对原设计影响较大。 实现较方案一简单 若进货单查询中要包括供应商的其他信息,不论供应商名称是否发生过变更,都要连接供应商表和供应商名称变更表,较方案一多连接一个表。,3)方案三,关系模型设计: 供应商名称变更表(*供应商编号,*供应商信息版本号,设定日期,供应商名称,电话,地址,) 进货单(*单号,日期,供应商编号,版本号,) 模型设计说明:供应商的所有属性均放在“供应商名称变更表”中 。,设计特点:,较方案二的特点是去掉供应商表,把供应商信息全部放到变更表中,一但供应商名称变化,该供应商其他信息要复制一遍,是缺点,但也是优点,即具有了变更供应商其他属性的能力,对信息变更不常发生的情况下, 重复的数据量很小。适合名称变化少量发生的情况。 思考和练习:分析是否符合NF,进行概要设计。,四)系名问题,记录变更:系名的变更的记录方法可类似地采用供应商名称变更的方案13的处理方法。 引用问题:一个进货单与供应商名称为11关系,可以用(供应商编号,供应商名称版本号)引用供应商名,但学生在读期间,系名可能发生多次变更,所以学生对系名可能为1多关系 系名信息不可能保存在学生表中 通过学生中系编号将引用到系名变更表中多个系名,例:有下列两个表:,department *设置日期 *系编号 系名称 1998-2-1 B001 数学系 1998-2-1 B002 物理系 1998-2-1 C001 计算机系 1999-5-1 C001 软件学院 2000-6-10 C001 信息学院,students *学号 姓名 系编号 98101 王海 C001 98102 李明 C001 98201 周涛 B001 98202 吴名 B001 98301 孙新 B002,完成下列select语句: 获得各系的最新系名 由于要输出学号为98101的学生1999-7-1的成绩单,如何获得当时的该学生所在系名?,获得各系的最新系名:,语句一:使用max聚集函数 select deptid,deptname from department a where setdate=(select max(setdate) from department where deptid=a.deptid group by deptid) 语句二:使用all操作符 select deptid,deptname from department a where setdate=all (select setdate from department where deptid=a.deptid),获得1999-7-1学生98101所在系名:,关键点:获得1999-7-1日前的最后一次设置的所有系名,实际在上例语句一子查询中加条件setdate=1999-7-1即可: select deptname from department a where setdate=(select max(setdate) from department where deptid=a.deptid and setdate=1999-7-1 group by deptid) 在上述查询中限制为98101学生所在系: select deptname from department a where setdate=(select max(setdate) from department where deptid=a.deptid and setdate=1999-7-1 group by deptid) -红色部分语句同上 and deptid in (select deptid from students where id=98101),思考和练习:使用all查询1999-7-1所有系名,在子查询中加条件:将出现1999-7-1后设置的系名“信息学院”: select deptid,deptname from department a where setdate=all (select setdate from department where deptid=a.deptid and setdate=all (select setdate from department where deptid=a.deptid ) and setdate=1999-7-1 正确的做法是在子查询和主查询中均加此条件。,引用方法小结:,供应商问题中进货单也可以用上述方法获得供应商名称,但由于查询使用了子查询(对包括供应商的进货单的查询将更复杂),当数据量很大时,效率明显降低。所以建议使用版本号的引用方法。 引用信息表达的是某一时刻的特征,如供应商问题中进货单对供应商名称的引用,可采用“编号+版本号”作为外键引用的方法得到名称。 引用信息表达的是某一时期的特征,如系名问题中学生信息引用各时期的系名,则必须结合日期用查询语句得到该日期的系统。,2.4 范式的局限对冗余的进一步讨论,一)突破范式限制 有时为了提高运行的时间效率需要

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论