资源描述
精选优质文档-倾情为你奉上课程设计说明书课程名称: 数据库系统课程设计 专 业: 班级: 设 计 人: 学 号: 山 东 科 技 大 学201年 7 月 24 日山 东 科 技 大 学课 程 设 计 任 务 书一、 课程设计题目:数据库课程设计二、 设计原始资料:数据库系统概论 王珊、萨师煊C+面向对象程序设计三、 设计应解决下列各主要问题: 1、设计特定的数据结构,用于存储数据表、视图、索引等数据库对象的信息,即建立数据库系统的数据字典; 2、设计特定的数据结构,用于存储数据表中的数据; 3、执行CREATE语句,创建数据表、视图、索引等数据库对象;创建数据表时需要包含主码、外码、唯一性约束、非空约束等完整性约束的定义; 4、执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUP BY、HAVING和ORDER BY子句,需要支持5种聚集函数;5、用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新操作,并给出提示信息;四、 设计说明书应附有下列图纸:无五、 小组分工说明:无 六、命题发出日期:2015-7-19设计完成日期:2015-7-26 指导教师评语成绩: 指导教师(签章):年月日专心-专注-专业目 录1需求分析说明 51.1课程设计的目的5 1.2课程设计的要求52 概要设计说明 6 2.1 程序的数据结构6 2.2 模块调用图 7 2.3DBMS程序模块的组成 83 详细设计说明 8 3.1主函数模块8 3.2 用户登录检查8 3.3数据库,数据表的建立9 3.4 SELECT语句的实现11 3.5 UPDATE和DELETE语句的实现134 调试分析145 用户使用说明146 课程设计总结 197源代码191需求分析说明1.1.课程设计的目的数据库系统课程设计是一门实践性课程,要求学生在教师的指导下,充分利用所学的数据库、数据结构、C/C+语言等相关知识,从底层做起,实现数据库的组织、存储、检索、更新和索引等功能。目的是让学生深刻理解关系数据库系统中数据和元数据的组织方式、存储方式、检索方式、更新方式和索引方式,同时培养学生的逻辑思维能力和锻炼学生的动手编程能力。1.2.课程设计的要求1、 设计特定的数据结构,用于存储数据表、视图、索引等数据库对象的信息,即建立数据库系统的数据字典;2、 设计特定的数据结构,用于存储数据表中的数据;3、 设计特定的数据结构,用于存储索引数据;4、 设计特定的数据结构,分别用于存储用户和访问权限的信息;5、 输入“help database”命令,输出所有数据表、视图和索引的信息,同时显示其对象类型;输入“help table 表名”命令,输出数据表中所有属性的详细信息;输入“help view 视图名”命令,输出视图的定义语句;输入“help index 索引名”命令,输出索引的详细信息;6、 解析CREATE、SELECT、INSERT、DELETE、UPDATE等SQL语句的内容;7、 检查SQL语句中的语法错误和语义错误;8、 执行CREATE语句,创建数据表、视图、索引等数据库对象;创建数据表时需要包含主码、外码、唯一性约束、非空约束等完整性约束的定义;9、 执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUP BY、HAVING和ORDER BY子句,需要支持5种聚集函数;10、 执行INSERT、DELETE和UPDATE语句,更新数据表的内容;更新过程中需要检查更新后的数据表是否会违反参照完整性约束。如果是,则提示违反哪一条完整性约束,并拒绝执行更新操作;如果否,提示数据表更新成功,并说明插入、删除或修改了几个元组。11、 当数据表的内容更新后,根据索引的定义,自动更新索引表的内容;12、 在有索引的数据表上执行查询语句时,首先利用索引找到满足条件的元组指针,然后通过指针到数据表中取出相应的元组;13、 执行GRANT语句,为用户授予SELECT、INSERT、DELETE、UPDATE权限;执行REVOKE语句,收回上述权限;14、 用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新操作,并给出提示信息;15、 将SELECT语句转化为关系代数表达式,再利用查询优化算法对关系代数表达式进行优化,输出优化后的关系代数表达式或SELECT语句。2概要设计说明2.1 程序的数据结构为了实现建立数据库的数据字典和存储数据表中的数据,设定了相应的类用来存储数据表的信息。class database /定义一个database类public: void CreateDatabase(); /数据库 void CreateTable(); /表 void DatabaseShow(); /定义显示所有数据函数 void DatabaseShow2(); /定义显示所有数据函数-访客模式 void DeleteTable(); /删除表中的信息 void DeleteRow(); /删除一个j记录内的信息 void Addrow(); /添加一行 void AddTable(); /添加一个表 void Change(); /更新数据 void select(); /选择语句 void grant(); /授权语句private: string DatabaseName; /数据库的名字 string TableName; /表的名字 string LeixingName; /数据类型的名字 string TableShuju; /表中的数据 string path; /路径 string Allpath; /全局路径 string pathrecord=0; / 全局记录路径默认为空 string x; char YN; /是否同意Y(同意)N(不同意) char a; /输入是否Y/N;2.2 模块调用图 main menu1 menu DBMS DBMS内的函数2.3 DBMS程序模块的组成DBMS由众多程序模块组成,它们分别实现DBMS复杂而繁多的功能。1、建立数据库,建立表;2、显示数据库;3、授权;4、删除行;5、添加表,添加行;6、更新,选择;3详细设计说明3.1 主函数模块首先调用菜单,输出主菜单;然后采用了文件操作,运用调用函数实现关于数据库的各种操作。3.2 用户登录检查 首先定义一个类,存储用户名和密码;class usersprivate: string name; string password;public: string n()return name; string p()return password; void n(string na)name=na; void p(string pa)password=pa;然后实现登录;int get_users(string name,string pass) ifstream FILE(users.txt); string s; char line100; int i=0,k=0; while(FILE.getline(line,100) s=line; if(i%2=0) uk.n(s); else if(i%2=1) uk.p(s); k+; i+; FILE.close(); for(int j=0;jk;j+) if(name=uj.n()&pass=uj.p() return 1; return 0;3.3数据库,数据表的建立本程序通过利用fstream文件流操作,实现了数据库和数据表的建立,但是对完整性约束的实现不是很成功。void database:CreateTable() /建表 int sum=0; char x; char s110,s210,s310,s410; int option; string ShuxingName;/属性字符名 string Allpath2; if(pathrecord=0) /判断当前是否建立数据库 coutERROR!endl建立数据库endl; cout请输入要建立的表名: TableName; Allpath2=pathrecord+shujuku.txt; ofstream Tdfile2(Allpath2.c_str(),ios:app); Allpath=pathrecord+TableName+.txt; /库路径 a=y; Tdfile2TableNameendl; Tdfile2.close(); while(a=y)|(a=Y) /文件打开,输入数据 ofstream Tdfile(Allpath.c_str(),ios:app); ofstream Tdfile3(Allpath2.c_str(),ios:app); /输入信息流 cout输入属性名称:ShuxingName; cout输入属性类型:LeixingName; TdfileShuxingName,.tLeixingName:t; Tdfile3ShuxingName,.tLeixingName:tendl; Tdfile3.close(); /检验属性类型,默认char和int和smallint if(LeixingName=char)| (LeixingName=CHAR) cout请输入数据TableShuju; TdfileTableShuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); /文件流关闭 /判断int和smallint是否符合输入要求 else if(LeixingName=smallint)| (LeixingName=SMALLINT) | (LeixingName=INT)| (LeixingName=int) cout请输入数据shuju; if(shuju=0)&(shuju=1000) Tdfileshuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); /文件流关闭 cout继续输入Y,停止输入Na;/在表内输入数据保证表数据完全 cout 请依次输入主码、外码、唯一值、非空值,没有输入NULLendl; scanf(%s%s%s%s,s1,s2,s3,s4); coutTableName的主码是s1endl; coutTableName的外码是s2endl; coutTableName的唯一值是s3endl; coutTableName的非空值是s4endl;3.4 SELECT语句的实现 本程序只实现了SELECT语句的单表查询,对连接查询,聚集函数等没有实现。void database:select() /进行选择语句 string TableMAX,shuxingMAX,leixingMAX,shujuMAX; string DatabaseName1,TableName1,Allpath1; cout请输入库名:DatabaseName1; cout请输入表名:TableName1; Allpath1=d:+DatabaseName1+TableName1+.txt; Allpath=d:+DatabaseName+TableName+.txt; if(strcmp(Allpath1.c_str(),Allpath.c_str()!=0) cout查找路径不存在!endl; /判断路径是不是正确的路径 int i=0,j=0,k1,k2,k3,sum; coutAllpath1下的数据为:endl; ifstream file(Allpath1.c_str(); char lineMAX; /读取每一行的数据 while(file.getline(line,MAX) Tablei=line; coutread line i:Tableiendl; i+; sum=i; for(j=0; ji; j+) k1=Tablej.find(,0); shuxingj=Tablej.substr(0,k1); k2=Tablej.find(:,0); leixingj=Tablej.substr(k1+2,k2-k1-2); k3=Tablej.length(); shujuj=Tablej.substr(k2+1,k3-k2); string xuanze; int flag; a=y; /类似于之前的操作,在这个表中,全表遍历找出这个属性 while (a=y)|(a=Y) flag=0; i=0; cout请输入要选择的属性名:xuanze; while(isum) if(strcmp(shuxingi.c_str(),xuanze.c_str()=0) cout这个属性为:shuxingi数据为:shujuiendl; flag=1; i+; else if(strcmp(shuxingi.c_str(),xuanze.c_str()!=0) i+; /使用标记flag来输出最后的结果 if(flag=1)cout选择成功endl; if(flag=0) cout没有该属性endl; cout是否继续选择其他的属性(y/n)a; if(a=n)|(a=N) break; else if(a=y)|(a=Y); else cout您输入有误,请重新输入endl; 3.5 UPDATE和DELETE语句的实现本程序实现的是对一个表的更新,删除行,对比较麻烦、抽象的SQL语句很难实现。4调试分析1. 创建表之后,数据表中数据的输出格式不美观。 2. 刚开始时曾忽略了一些变量参数的标识&和“*”,使调试程序时费时不少。今后应重视确定参数的变量和赋值属性的区分和标识。 3.开始时建立数据库和建立表没法成功的完成,最后在翻阅图书时才找到有效的解决方法。 4.通过本次试验学会通过路径查找文件的方法,很有用处,而且这样对数据库的理解更深刻。 5.开始对表的插入和删除存在不一致的现象,经过仔细调试,终于得以解决。5用户使用说明1. 本程序的运行环境为DOS操作系统,运行文件为:gkl.exe。2. 首先建立一个名为“users.txt”的文件,用于存储用户名和密码。3. 进入程序后即显示文本方式的用户界面:首先是访客登陆: 然后是管理员登录:输入用户名和密码之后进入建立数据库操作:建立表:显示数据库:授权:选择:退出系统: 6课程设计总结通过这次数据库课程设计,使我对软件的界面设计有了一个比较深刻的了解,对数据库的性能有了清晰的认识,使我感觉到到,一个优秀的软件,不仅仅是可以运行的,更应该具有人性化的界面,协调的布局,合理的结构,良好的性能和一定的容错性。一个人要完成所有的工作是非常困难和耗时的。在以后的学习中我会更加注意各个方面的能力的协调发展,选择一两门技术进行深入研究,成为一个既可以统筹全局,又有一定技术专长的优秀的程序开发人员。这次课程设计对我来说很不容易,平时都是放到整个学期来完成,而这次只有小学期一个周的时间。虽说最终做出来了,但是效果却不能令我满意。在这个过程中,我走了很多弯路,比如,C+中有许多可以直接调用的类,起初我不知道它们的存在,便自己编写,花费了时间而且没达到预期的效果,多次查找资料仔细分析后,直接调用了C+中的现有资源。7 源代码#include #include #include #include #include #include #define TABLE_LENTH 20 /表的长度#define MAX_DATA_LEN 20 /最大字段数#define MAX_NAME_LENTH 20 /字段名的最大长度#define MAX_LEN_FILE_NANE 127 /文件名的最大长度#define MAX_STRING_LENGTH 127 /字符串的最大长度#define OK 1#define ERROR 0#define INITSTATUS -1 /初始状态using namespace std;int MAX=100;class usersprivate: string name; string password;public: string n()return name; string p()return password; void n(string na)name=na; void p(string pa)password=pa;users u100;users person;union Elemtype/定义元素类型char CHAR; /字符型char STRINRMAX_STRING_LENGTH; /字符串型int INT;/整数型double DOUBLE;/浮点型;struct Node/定义元素节点类型union Elemtype arrMAX_DATA_LEN;struct Node *next;struct Data/字段基本信息char strNameMAX_NAME_LENTH; /字段名int nLen; /字段长度char cType; /字段类型;struct DataNode/记录字段基本信息的节点struct Data data;/字段基本信息结构体struct DataNode *pNext;/指针;struct Table/记录所有字段信息的表结构体int nLen;/表的长度struct Data HeadMAX_NAME_LENTH;/记录字段全部信息的数组int nCount;/记录数据容量;struct File/定义文件结构struct Table *pTable;/表头指针struct Node *pHead;/数据区指针int nCount;/数据区容量;class database /定义一个database类public: void CreateDatabase(); /数据库 void CreateTable(); /表 void DatabaseShow(); /定义显示所有数据函数 void DatabaseShow2(); /定义显示所有数据函数-访客模式 void DeleteTable(); /删除表中的信息 void DeleteRow(); /删除一个j记录内的信息 void Addrow(); /添加一行 void AddTable(); /添加一个表 void Change(); /更新数据 void select(); /选择语句 void grant(); /授权语句private: string DatabaseName; /数据库的名字 string TableName; /表的名字 string LeixingName; /数据类型的名字 string TableShuju; /表中的数据 string path; /路径 string Allpath; /全局路径 string pathrecord=0; / 全局记录路径默认为空 string x; char YN; /是否同意Y(同意)N(不同意) char a; /输入是否Y/N;void database:CreateDatabase() /建一个数据库 cout请输入建立数据库名称: DatabaseName; path=d:+DatabaseName; /路径=在D盘内,加上数据库的名字 pathrecord=path+; /全局记录路径 path=md +path; /MD创建路径 system(path.c_str(); /把字符串转入命令void database:CreateTable() /建表 int sum=0; char x; char s110,s210,s310,s410; int option; string ShuxingName;/属性字符名 string Allpath2; if(pathrecord=0) /判断当前是否建立数据库 coutERROR!endl建立数据库endl; cout请输入要建立的表名: TableName; Allpath2=pathrecord+shujuku.txt; ofstream Tdfile2(Allpath2.c_str(),ios:app); Allpath=pathrecord+TableName+.txt; /库路径 a=y; Tdfile2TableNameendl; Tdfile2.close(); while(a=y)|(a=Y) /文件打开,输入数据 ofstream Tdfile(Allpath.c_str(),ios:app); ofstream Tdfile3(Allpath2.c_str(),ios:app); /输入信息流 cout输入属性名称:ShuxingName; cout输入属性类型:LeixingName; TdfileShuxingName,.tLeixingName:t; Tdfile3ShuxingName,.tLeixingName:tendl; Tdfile3.close(); /检验属性类型,默认char和int和smallint if(LeixingName=char)| (LeixingName=CHAR) cout请输入数据TableShuju; TdfileTableShuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); /文件流关闭 /判断int和smallint是否符合输入要求 else if(LeixingName=smallint)| (LeixingName=SMALLINT) | (LeixingName=INT)| (LeixingName=int) cout请输入数据shuju; if(shuju=0)&(shuju=1000) Tdfileshuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); /文件流关闭 cout继续输入Y,停止输入Na;/在表内输入数据保证表数据完全 cout 请依次输入主码、外码、唯一值、非空值,没有输入NULLendl; scanf(%s%s%s%s,s1,s2,s3,s4); coutTableName的主码是s1endl; coutTableName的外码是s2endl; coutTableName的唯一值是s3endl; coutTableName的非空值是s4endl;void database:DatabaseShow() /数据库的指定表输出全部信息 int i; char lineMAX; /定义三个字符串用来检查输入路径是否正确 string DatabaseName1,TableName1,Allpath1; cout请输入要显示的数据库名:DatabaseName1; cout请输入要显示的表名:TableName1;/检查路径是不是正确 Allpath1=d:+DatabaseName1+TableName1+.txt; coutAllpath下的数据为:endl; cout t : :endl; ifstream fin(Allpath1.c_str(); i=0; while(fin.getline(line,100) coutread line i : lineendl; i+; void database:Addrow() /添加一行的数据,即一个数据记录 int i=0,j=0,sum=0,SUM; char s; string DatabaseName1,TableName1,Allpath1; cout请输入要加行的数据库:DatabaseName1; cout请输入要加行的表:TableName1; /需要确定是不是符合要求 Allpath1=d:+DatabaseName1+TableName1+.txt; Allpath=d:+DatabaseName+TableName+.txt;/ if(strcmp(Allpath1.c_str(),Allpath.c_str()!=0)/ / cout路径不存在!endl;/ if(strcmp(Allpath1.c_str(),Allpath.c_str()=0) ifstream ATfile2(Allpath.c_str(); s=ATfile2.get(); while(s!=EOF) if(s=:) sum+; s=ATfile2.get(); ATfile2.close(); SUM=sum; string ShuxingName; string LeixingName; char a=y; while(a=y)|(a=Y) sum=0; ofstream Tdfile(Allpath.c_str(),ios:app); cout输入属性名称:ShuxingName; cout输入属性类型:LeixingName; TdfileShuxingName,.tLeixingName:t; /当输入属性类型是char的时候 if(LeixingName=char)| (LeixingName=CHAR) cout请输入数据TableShuju; TdfileTableShuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); /当输入的属性类型是int或者smallint的时候 else if(LeixingName=smallint)| (LeixingName=SMALLINT) | (LeixingName=INT)| (LeixingName=int) cout请输入数据TableShuju; TdfileTableShuju ; sum-; if(sum=0) Tdfilen; Tdfile.close(); cout是否继续输入Y/Na; void database:AddTable() /添加一个表格,在指定的数据库中 char a=y,x; int j=0,sum=0; string DatabaseName1,TableName1,Allpath1; cout请输入要添加到的数据库:DatabaseName1; cout请输入要增加的表: TableName1; /判断是否符合 Allpath1=d:+DatabaseName1+TableName1+.txt; Allpath=d:+DatabaseName1+shujuku.txt; int n,m; ofstream Tfile(Allpath.c_str(),ios:app); TfileTableName1endl; Tfile.close(); string ShuxingName; string LeixingName; string pname; while(a=y)|(a=Y) ofstream TTTfile(Allpath1.c_str(),ios:app); ofstream Tfile(Allpath.c_str(),ios:app); coutAllpath.c_str()endl; cout输入属性名称:ShuxingName; cout输入属性类型:LeixingName; TTTfileShuxingName,.tLeixingName:t; TfileShuxingName,.tLeixingName:tendl; Tfile.close(); cout请输入元组数据:endl; j+; while(j!=0) cout请输入数据pname; TTTfilepname
展开阅读全文