课程设计说明书设计题目:数据库课程设计专业:计算机科学与技术班级:2010级5班设计人:王露山东科技大学2012年04月07 日摘要:本次课程设计,研究了如何判断输入的模式分解是否保持无损连接性,提示用户输入关系模式的属性集,函数依赖集以及模式分解,利用算法6.的表格法,运行程序,输出是否具有无损连接性。
用java语言实现,在eclipse上运行,且只考虑了分解的无损连接性而没有考虑函数依赖的保持性。
目录:任务书-------------------------------------------------------------------------------------2教师评语---------------------------------------------------------------------------------3摘要---------------------------------------------------------------------------------------4题目要求--------------------------------------------------------------------------------4需求分析--------------------------------------------------------------------------------4程序设计--------------------------------------------------------------------------------6结果分析--------------------------------------------------------------------------------15实验总结--------------------------------------------------------------------------------20附录(使用说明)-------------------------------------------------------------------21正文:1. 题目:选择一种高级语言实现判别一个分解的无损连接性输入:某一个关系模式的属性集、函数依赖集和该关系模式的一个分解 输出:分解是否保持无损连接性 要求:(1)按算法6.2和6.4实现(P190)(2)能给出根据模式的分解形成初始表格(3)给出根据每一个函数依赖表格的变化情况 (4)提供课程设计报告2.需求分析1.关系模式R(U,F),ρ={R 1(U 1,F 1),R 2(U 2,F 2),…, R k (U k ,F k )}是R(U,F)的一组子集,若U 1⋃U 2⋃…⋃U k =U ,则称 ρ 是R(U,F)的一个分解(Decomposition)。
分解有两个准则,无损连接性和函数依赖的保持性。
无损连接性的定义为 设关系模式R(U,F), ρ={R 1,R 2,…,R k }是分解R 所得的一组关系模式,对于R 的满足F 的任一个关系实例r ,都有:成立。
即r 等于它在R i 上投影的自然连接,则称此分解为满足F 的具有无损连接性的分解。
2.分解的无损连接性判断定理6.4:设关系模式R(U,F), ρ={R 1,R 2}是R 的一个分解,当且仅当U 1⋂U 2→U 1-U 2或 U 1⋂U 2→U 2-U 1∈F +时,则分解ρ具有无损连接性。
3.算法6.2 {判断分解ρ的无损连接性} 输入:R(U,F),U=A 1A 2…A n ; ρ={R 1,R 2,…,R k }输出:如果ρ具有无损连接性,输出True ,否则输出False 。
(1) 构造一个n 列k 行的二维表T 。
若A j ∈R i ,则T ij =a j ;否则T ij =b ij 。
(2) flag:=True; Do While Flag Flag:=False;For 每一个X →Y ∈F DoFor T 中的任意两行t j ,t m Do)()()(21r r r r k R R R ∏∞∞∏∞∏=If t j[X]=t m[X] And t j[Y]≠t m[Y] ThenEQUAY(t j,t m);Flag:=True;(3) For T的每一行t DoIf t=a1a2…a n Then Return(True);Return(False).故根据定理6.2和6.4的算法和定理,可以得出判断关系模式的分解是否保持无损连接性的充分必要条件是U1⋂U2→U1-U2或U1⋂U2→U2-U1∈F+时,则分解ρ具有无损连接性。
所以问题转变成为集合的并差问题,然后根据6.2算法再加以完善,就可以编写程序来实现这一功能了。
当然,关系模式分解的另一个准则是函数依赖的保持性,这两个准则虽然没有什么直接的关系,却决定了一个关系模式可以达到哪一个范式,不能单一的进行讨论,都需要进行分析,现在,为简便起见,我们只讨论一个关系模式的分解是否保持着无损连接性,暂时不讨论其函数依赖的保持性3.程序设计3.1粗略设计根据算法6.2,利用表格法进行判断,以下是表格法的详细步骤。
算法:ρ={R1<U1,F1>,R2<U2,F2>,...,R k<U k,F k>}是关系模式R<U,F>的一个分解,U={A1,A2,...,A n},F={FD1,FD2,...,FD p},并设F是一个最小依赖集,记FD i为X i →A lj,其步骤如下:①建立一张n列k行的表,每一列对应一个属性,每一行对应分解中的一个关系模式。
若属性A j U i,则在j列i行上真上a j,否则填上b ij;②对于每一个FD i做如下操作:找到X i所对应的列中具有相同符号的那些行。
考察这些行中l i列的元素,若其中有a j,则全部改为a j,否则全部改为b mli,m 是这些行的行号最小值。
如果在某次更改后,有一行成为:a1,a2,...,a n,则算法终止。
且分解ρ具有无损连接性,否则不具有无损连接性。
对F中p个FD逐一进行一次这样的处理,称为对F的一次扫描。
③比较扫描前后,表有无变化,如有变化,则返回第步,否则算法终止。
如果发生循环,那么前次扫描至少应使该表减少一个符号,表中符号有限,因此,循环必然终止。
举例1:已知R<U,F>,U={A,B,C},F={A→B},如下的两个分解:①ρ1={AB,BC}②ρ2={AB,AC}判断这两个分解是否具有无损连接性。
用无损连接的定理来解。
方法一:因为AB∩BC=B,AB-BC=A,BC-AB=C所以B→A F+,B→C F+故ρ1是有损连接。
方法二:因为AB∩AC=A,AB-AC=B,AC-AB=C所以A→B F+,A→C F+故ρ2是无损连接。
下面举个例子来说明表格法【例】已知R<U,F>,U={A,B,C,D,E},F={A→C,B→C,C→D,DE→C,CE→A},R的一个分解为R1(AD),R2(AB),R3(BE),R4(CDE),R5(AE),判断这个分解是否具有无损连接性。
解:用判断无损连接的算法来解。
①构造一个初始的二维表,若“属性”属于“模式”中的属性,则填a j,否则填b ij。
见表1.表1.②根据A→C,对上表进行处理,由于属性列A上第1、2、5行相同均为a1,所以将属性列C上号b13(取行号最小值)。
③根据B→C,对上表进行处理,由于属性列B上第2、3行相同均为a2,所以将属性列C上的b行号最小值)。
表4.④根据C→D,对上表进行处理,由于属性列C上第1、2、3、5行相同均为b13,所以将属性列上的值均改为同一个符号a4。
表5.⑤根据DE→C,对上表进行处理,由于属性列DE上第3、4、5行相同均为a4a5,所以将属性列。
表73⑤根据CE→A,对上表进行处理,由于属性列CE上第3、4、5行相同均为a3a5,所以将属性列。
1⑦通过上述的修改,使第三行成为a1a2a3a4a5,则算法终止。
且分解具有无损连接性。
3.2详细设计(2000)要使本程序正确运行下去,需要解决的问题很多,下面,举个例子,来演示本程序的运行。
【例】已知R<U,F>,U={A,B,C,D,E},F={A→C,B→C,C→D,DE→C,CE→A},R的一个分解为R1(AD),R2(AB),R3(BE),R4(CDE),R5(AE),判断这个分解是否具有无损连接性。
(1)首先,需要解决的问题是关系模式属性集,关系模式函数依赖集,模式分解的输入,此时需要有个用户说明书,告诉用户该怎么输入,输入什么,输入的东西是什么格式的,例如,必须输入U={ A,B,C,D,E},定义一个字符型数组stringAttribute[],InputStreamReader isra=newInputStreamReader(System.in);char[]stringAttribute=new char[20];isra.read(stringAttribute);依次存入ABCDE五个属性。
为了方便输出,定义一个字符型变量comma=’,’还有定义一个字符型数组brace[]为左右大括号。
其次定义字符数组dependence[]来储存输入的函数依赖,modecomposition[]来储存输入的模式分解。
最后在用一个isra.read(stringAttribute)输出就好了。
(2)为了确保输入的信息是否正确,依次输出System.out.println(“您输入的模式的属性集为:”+new String(stringAttribute));System.out.println(“您输入的模式的属性集为:”+new String(dependence));System.out.println(“您输入的模式的属性集为:”+newString(modecomposition));提示用户检查是否输入正确System.out.print("输入是否正确?y/n");Scanner scanner = new Scanner(System.in);char character = (char) scanner.nextByte();if (scanner.equals('y')) {System.out.print("go on");continue label;}else {System.out.print("error");Break;}若是输入正确,则执行表格生成Table.java 见结果分析中的截图4.Package TableChangepublic class Table {public static void main( String args[])throws DBFException, IOException {DBFField field = new DBFField();field.setName("Table"); // give a name to the fieldfield.setDataType( DBFField.FIELD_TYPE_C); // and set its typefield.setFieldLength( 5); // and length of the field DBFField fields[]=new DBFField[5];fields[0] = new DBFField();fields[0].setName("A");fields[0].setDataType( DBFField.FIELD_TYPE_C);fields[0].setFieldLength( 5);再依次fields[1] = new DBFField();fields[1].setName("B");fields[1].setDataType( DBFField.FIELD_TYPE_C);fields[1].setFieldLength( 5);fields[2] = new DBFField();fields[2].setName("C");fields[2].setDataType( DBFField.FIELD_TYPE_C);fields[2].setFieldLength( 5);fields[3] = new DBFField();fields[3].setName("D");fields[3].setDataType( DBFField.FIELD_TYPE_C);fields[3].setFieldLength( 5);fields[4] = new DBFField();fields[4].setName("E");fields[4].setDataType( DBFField.FIELD_TYPE_C);fields[4].setFieldLength( 5);public class Function{public static void main(string[] args){//这个函数的目的是用来判断用输出表格中的数据Char [][] data=new char[3][5]; //二维数组记录表格中的数据System.out.print("属性 " );for(int temp=0;temp<5;temp++)System.out.print(" "+stringAttribute[temp]);System.out.print("\n");System.out.println("--------------------------------------");这样输出的结果就是属性 A B C D E--------------------------------------表格的最左边是函数依赖dependence[]若“属性”属于“模式”中的属性,则填a j,否则填b ijSystem.out.print(dependence[0]);for(int j=0;j<5;j++){if(stringAttribute[0]==dependence[j])//判断属性是否属于模式中的属性,若是,则填a jdata[0][j]='a[j]';elsedata[0][j]='b[i][j]';//若不属于,则填b ij}for(int i=0;i<5;i++){System.out.print(" ");if(data[0][i]=='a'){System.out.print(data[0][i]);System.out.print(i);}else{System.out.print(data[0][i]);System.out.print("0"+i);}}System.out.print("\n");这样执行输出结果为第二行AB→C a1 a2 a3 b14 b15依次判断关系依赖集中的各个属性System.out.print(dependence[1]);for(int j=0;j<5;j++){if(stringAttribute[1]==dependence[j])data[1][j]='a[j]';elsedata[1][j]='b[i][j]';}for(int i=0;i<5;i++){System.out.print(" ");if(data[1][i]=='a'){System.out.print(data[1][i]);System.out.print(i);}else{System.out.print(data[1][i]);System.out.print("1"+i);}}System.out.print("\n");同理,输出第三行C→D b12 b22 a3 a4 b25System.out.print(dependence[2]);for(int j=0;j<5;j++){if(stringAttribute[2]==dependence[j])data[2][j]='a[j]';elsedata[2][j]='b[i][j]';}for(int i=0;i<5;i++){System.out.print(" ");if(data[2][i]=='a'){System.out.print(data[2][i]);System.out.print(i);}else{System.out.print(data[2][i]);System.out.print("2"+i);}}System.out.print("\n");D→E b31 b32 b33 a4 a5在Function函数中直接输出,见图1.图1.(3)改表对于每一个FD i做如下操作:找到X i所对应的列中具有相同符号的那些行。