还剩17页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
图表
(1),解析系统的逻辑处理结构注释说明1读取,写入数据库调用Create语句,创建符合条件的dbf文件,存入数据库,或读取文件,修改表单属性2读取,写入数据库从数据库中读取表单,修改表中记录,再写入库中3只读取数据库读取选择相关信息,反馈给用户
④底层数据库为上层用户界面提供反馈信息
2.2系统文件构成分析图表
(2),解析系统的文件结构程序文件文件概述MySql.c主程序文件,包括main主函数在内,以及对各个语句的判断Sql.c包括所有的sql语句处理函数,前期的读入,词句分析函数,以及分析后调用函数处理文件Dbf.c包括所有对.dbf文件的创建,修改,删除等的函数Sql.hSql语句处理函数的定义Dbf.h处理文件的函数的定义演示文档对初学者的提示,以及异常输入的演示
2.3系统总体流程分析图表
(3),程序的主要执行流程
2.4系统基本设计概念1)系统总体设计分析系统解析了sql语句,包括对表的创建,删除,对表内记录的插入,删除等其中
(1)表定义中列(属性)的类型至少支持三种integer、char、float;
(3)记录的插入、删除、修改等,即时更新原始数据;
(4)记录的搜索至少实现按主键查找,只是主键上的范围查找,包含遍历2)本次select语句的模块完善分析和结构分析
(1)增加了groupby语句,可以处理groupby语句的各个条件,包括having语句或和orderby连接使用;
(2)完善了order的排序模块,从单属性排序优化到了多属性排序;
(3)SortGroupRec优化了内部排序,加快了大数据处理速度;
2.5程序模块说明
2.
5.1Main()模块1目标协调各其他各模块之间的关系最终负责系统运行2程序文件MYSQL.c3主要数据结构字符串(用来存储用户的输入数据)4调用的其他模块文件处理模块(dbf),处理操作模块(sql)5算法c面向过程的函数处理机制6逻辑流程图intmain{Show;//界面构造Getsinput;//得到用户输入,存储Switch{caseCREATE:Create...;break;创建记录caseSELECT:Select...;break;选择记录caseINSERT:Insert...;break;插入记录caseUPDATE:Update...;break;更新记录caseDELETE:Delete...;break;删除记录caseSELECT:Select...;break;查询记录caseQUIT:return;}Judge;//判断用户是否继续操作,继续或者结束程序Return0;}1其中界面和读取操作算是前期的处理,属于数据的初始化阶段;2Switch属于对输入的判断,然后在其函数体内执行操作,属于本函数的主要组成部分,语句select是本组这次设计的重点完善对象;
2.
5.2数据操作处理模块1)目标完成对底层数据的各种操作,方便上层的调用,简化操作2)程序文件dbf.cdbf.h3)主要数据结构以结构体为主struct_DbfHead{chardbFlag;charyear;charmonth;charday;intrecCounts;shortfirstRecAddr;shortrecLen;charundo
[20];};typedefstruct_DbfHeadDbfHead*pDbfHead;//字段描述结构体定义struct_FieldDcp{charfieldName
[10];charundo1;charfieldType;shortoffset;charundo2
[2];charfieldLen;charnumDecis;charundo3
[14];};typedefstruct_FieldDcpFieldDcp*pFieldDcp;//字段数据结构体定义struct_DbfField{char*fieldData;charfieldName
[10];charfieldType;charfieldLen;charfieldDcis;shortoffset;};typedefstruct_DbfFieldDbfField*pDbfField;//记录结构体定义struct_DbfRec{chardelFlag;DbfFieldfield[MAX_FIELD_COUNTS];intrealCounts;};typedefstruct_DbfRecDbfRec*pDbfRec;//dbf文件句柄定义struct_DbfHand{charfilename
[50];DbfHeadheader;DbfRecrec;longcurRecNo;longcurFpAddr;FILE*fd;};typedefstruct_DbfHandDbfHand*pDbfHand;同时也在dbf.h中进行了一些宏定义,方便其它函数直接使用#defineGET_YEAR0#defineGET_MONTH1#defineGET_DAY2#defineFOX_VERISON_INFO262#defineWIN_32#defineMAX_FIELD_COUNTS40//字段类型#defineFIELD_CHAR_TYPE0x43#defineFIELD_DATE_TYPE0x44#defineFIELD_FLOAT_TYPE0x46#defineFIELD_LOG_TYPE0x4C#defineFIELD_MEMO_TYPE0x4D#defineFIELD_NUMIC_TYPE0x4E#defineFIELD_INT_TYPE0x49//条件查询#defineCON_SMALL0#defineCON_EQUAL1#defineCON_LARGE2//排序#defineCON_SORT_INCREASE0#defineCON_SORT_DECREASE1#defineTRUE1#defineFALSE0#defineBOOLint4调用的其他模块无5算法C语言面向过程的设计*
2.
5.3解释器模块(由于本组只完善修改了数据查询语句,所以在这里只分析select语句,其他模块只简单阐述,不再仔细分析)1目标命令解释器的基本功能就是将用户的输入命令进行语法分析和语义解析并得到需要的命令参数最后根据命令参数对底层数据进行操作2程序文件sql.h、sql.cpp3主要数据结构有意字符串,一个以回车或空格或标志符来分割的有独立含义的字符串不包括空格回车但标志符入“;”视作有意字串如一条命令4调用其他模块数据操作处理模块5算法排序算法(内部和外部)6)模块内部详细分析(select语句解释模块,intSql_SELECT)
(1)首先判断第一个操作是否是selectfori=0;sql_select[i]==;i++;//处理输入的空格,以后每次读入都会有这个语句for;sql_select[i]!=;i++{sn[i]=tolowersql_select[i];//将语句转化成小写,存入snt++;}sn[t]=\0;//结束符,表示字符串结束然后,strcmpsn“select”,如果是select,则继续后续的读入处理分析,否则,返回
(2)读取select后的字符串,即所要查询的属性,存入s[][]中Do{t=0;snum++;//代表select后的属性的数量for;sql_select[i]==;i++;//处理输入中的多余的空格for;sql_select[i]!=;i++{s[snum][t]=tolowersql_select[i];//转化成小写字符t++;}s[snum][t]=\0;//结束符,表示这个属性结束ifs[snum][t-1]==;//如果遇到“;”字符,表示输入结束,break跳出{break;}ifstrcmps[snum]from==0{//如果遇到from字符串,则表示select结束,break跳出读取from后的表的信息break;}}while1;//循环处理读取字符串,直到以上两种情况,结束然后判断是否有查询聚集函数forp=0;psnum;p++//判断有无聚集函数,并记录在st中比较判断是哪个聚集函数,在这里以count为例说明执行过程ifstrcmps[p]count==0{cnum++;//记录count的数量ifstrcmps[p]*//判断count后是否有*{sign=1;//标记含有*strcpysts[p+1];//记录在st串中st[strlens[p+1]]=\0;//结束符}else//同上,没有*的情况{strcpysts[p+1];st[strlens[p+1]]=\0;sign=2;}strcpyst_g[cnum-1]s[p+1];}数据测试
(3)依次读取wheregrouphavingorder等后面的属性,分别存入w[][]g[][]h[][]o[][]数组,方法同上在这里不在重复注意,在读取from后面的所要查询的表的信息时,在后面加上.dbf方便后期的查询f[fnum][t]=.;f[fnum][t+1]=d;f[fnum][t+2]=b;f[fnum][t+3]=f;f[fnum][t+4]=\0;读取之后分别标记各个语句的存在,即group_yes–是否存在groupwhere_yes–是否存在wherewhere_group–where和group同时存在
(4)group语句的处理解释
①为了提高排序的效率,使用了内部排序,即打开所要查询的表之后把记录放入到内存(group_rec_t[])中///将符合条件的记录放入到group_rec_t中,然后排序recount=GetRecCountshand;//记录查询的表中有多少元组,hand是表的指针pDbfRecgroup_rec_t[recount+1];//在内存中开辟一块空间存储表中元组的地址GotoTophand;//跳到表的开始然后依次读取forj=0;jrecount;j++//循环将元组信息放入的内存中{ifNULL==rec=pDbfRecmallocsizeofDbfRecreturn0;ifNULL==rec=GetCurRechand{return0;}group_rec_t[j]=rec;GoNextRechand;//跳到下一个,继续循环}//内存中进行记录的排序SortGroupRecgroup_rec_trecountggnum;排序函数解释如下///内部排序,快速,高效,但占用了交大的内存///在内存中对gRec中记录进行排序,根据g数组中的groupby后的属性进行比较///此处采用了冒泡排序,代码简单明了,易于看懂voidSortGroupRecpDbfRec*gRecintncountcharg
[100]
[20]intg_sum{ifncount2||g_sum1return;pDbfRectemp;intijkp;fori=0;ig_sum;i++putsg[i];intfieldNum=0yes_to_swap=0;intsumOfRec=gRec
[0]-realCounts;longdoublesuma=0;longdoublesumb=0;///临时变量,用于排序//比较每两个元组,判断是否需要交换fori=0;incount-1;i++{forj=i+1;jncount;j++{yes_to_swap=0;charcmpstr
[20];fork=1;kg_sum;k++//依次查找每一个属性,标记{strcpycmpstrg[k];forp=0;psumOfRec;p++ifstrcmpcmpstrgRec
[0]-field[p].fieldName==0{fieldNum=p;//属性的标号,以后每次比较的就是这个属性break;}switchgRec
[0]-field[fieldNum].fieldType//判断这个属性是什么类型{//然后根据每种属性类型进行处理,比较caseFIELD_DATE_TYPE:caseFIELD_CHAR_TYPE:putsgRec[i]-field[fieldNum].fieldData;putsgRec[j]-field[fieldNum].fieldData;ifstrcmpgRec[i]-field[fieldNum].fieldDatagRec[j]-field[fieldNum].fieldData0{//判断如果后面的元组小于前面的,进行标记yes_to_swap=1;break;}caseFIELD_FLOAT_TYPE:caseFIELD_INT_TYPE:caseFIELD_NUMIC_TYPE:forp=0;gRec[i]-field[fieldNum].fieldData[p]!=.gRec[i]-field[fieldNum].fieldData[p];p++{suma=suma*10+gRec[i]-field[fieldNum].fieldData[p]-0;}forp=0;gRec[j]-field[fieldNum].fieldData[p]!=.gRec[j]-field[fieldNum].fieldData[p];p++{sumb=sumb*10+gRec[j]-field[fieldNum].fieldData[p]-0;}ifsumasumbyes_to_swap=1;break;}//如果需要交换ifyes_to_swap==1{temp=gRec[i];gRec[i]=gRec[j];gRec[j]=temp;break;}}}}return;}数据测试单表sc,单个字段排序sno,带有聚集函数avg
(5)order语句的处理ifo
[0]
[0]!=0首先判断是否有order存在,然后根据后面的属性进行升序或者降序排序ifstrcmpo[i+1]asc==0||strcmpo[i+1]ASC==0SortDbfhand1order_filedidCON_SORT_INCREASE;//升序elseifstrcmpo[i+1]desc==0||strcmpo[i+1]DESC==0SortDbfhand1order_filedidCON_SORT_DECREASE;//降序elseSortDbfhand1order_filedidCON_SORT_INCREASE;//缺省为升序多个表,where是否存在,不同情况处理类似不在重复说明数据测试
(6)开始单表查询单表查询就是在单个表中对所选择属性进行查找,输出判断条件时的多种情况的不同分析单个属性则不需要判断每个条件中都要判断where的存在,是否查询所有属性,即是否有*然后在每种情况中读取属性,判断是否满足查询条件ifstrcmpf1-fieldDataw
[2]==0strcmpf3-fieldDataw
[6]==0{//如果满足条件,则加入到hands中AddRechandsrec;ifsign2!=1{fork=0;ksnum;k++{f2=GetFiledByNamehandrecs[k];ifsign==1printf%-11s|f2-fieldData;}//格式化输出printf\n;fork=0;ksnum;k++printf--------------+;printf\n;}}其他情况与此类似,不再重复,下面是测试数据(多条件判断的)(单个条件判断的)
(7)开始双表查询双表查询与单表类似,但是要分别提取两个表的属性组合在一起然后显示出来,简单流程如下提取语句如下/*******提取第一个表中的表名和属性*********/fork=0;w
[0][k]!=.;k++{table1_name[j1]=w
[0][k];j1++;}table1_name[j1]=.;//在表的名字后面加上.dbf,查找提取属性table1_name[j1+1]=d;table1_name[j1+2]=b;table1_name[j1+3]=f;table1_name[j1+4]=0;k++;for;w
[0][k]!=0;k++{table1_filed[j1_1]=w
[0][k];j1_1++;}table1_filed[j1_1]=0;/*******提取第一个表中的表名和属性结束*********//*******提取第二个表中的表名和属性****************/fork=0;w
[2][k]!=.;k++{table2_name[j2]=w
[2][k];j2++;}table2_name[j2]=.;table2_name[j2+1]=d;table2_name[j2+2]=b;table2_name[j2+3]=f;table2_name[j2+4]=0;k++;for;w
[2][k]!=0;k++{table2_filed[j1_2]=w
[2][k];j1_2++;}table2_filed[j1_2]=0;/*******提取第二个表中的表名和属性结束****************/其他判断类似,测试数据如下多表,而且存在having的查询数据
(8)不存在where的情况,即没有判断条件的情况,输出分组排序后的信息即可但仍要判断是否有*的存在,即是否输出所有属性过程和单双表类似,只不过没有选择判断的部分测试数据如下
(9)容错机制程序在输入的过程中,用户可能会有许多的错,所以程序中加了许多判断错误的条件当有错误发生时返回上一阶段,并提示错误信息异常数据如下Select输入格式错误,不符合解释程序
④开始界面,及各个语句的反馈信息SQL语句解析内部SQL语句解析用户部分*Select查找记录Update更新记录Delete删除记录Alter修改属性Create创建.dbf表Insert插入记录语句处理解析部分创建修改.dbf文件调用不同函数,分类处理语句处理判断不符合格式,返回界面修改,更新记录信息查找记录,回显给用户属性,字段,表单,语句等的处理错误,返回
①②③程序开始,显示界面,读入用户输入,存入sql数组并进行判断便于后序的分析处理处理order语句,讲元组存入select文件,然后筛选需要的信息输出读取错误,返回Insert插入记录本小组主要完善了select语句,故在此不做其他语句的详细分析判断词句的读入,选择后序的处理语句Alter修改表属性Delete删除记录Updata更新记录Select选择语句Create创建文件将sql数组的字符存入sql_select数组,然后读取字符,分别存入sfwohg数组作为select,where的属性进行后续处理处理group语句,从表中读取信息,放入内存,使用冒泡排序,筛选所需元组,属性等判断是否有orderYN判断格式正确不符合输入条件,直接返回上级判断单双表查询表单不符合条件,直接返回从表中提取元组,判断,按照要求筛选用户需要的进行输出分别从两个表中提取元组,判断,按照要求筛选用户需要的进行输出不是单表也不是双表,直接返回上一级单个表两个表显示查询结构,提示是否继续进行是否继续不继续,程序结束继续使用,返回开始界面继续进行不是Y也不是N,则继续询问打开所要查询的表,读取按要求多属性排序(冒泡)处理聚集函数打印查询的表头信息每次打开一个表的时候都判断表的存在,不存在则回显“打开文件失败!”给用户提示
①调用Aggrega1函数处理聚集函数,记录所要查询的信息判断是否满足条件,输出打开表单,查找属性判断条件时有多种情况,如单属性还是多属性比较,是否查询所有属性,即是否有*存在等,分情况分析,所以代码很多重复的部分,在这里只阐述重点打开,提取第二个表中的属性,存储打开,提取第一个表中的属性,存储在新的,已经存储了两个表信息的表中进行查询,筛选,符合条件的输出。