简单的DBMS.docx
《简单的DBMS.docx》由会员分享,可在线阅读,更多相关《简单的DBMS.docx(31页珍藏版)》请在冰豆网上搜索。
![简单的DBMS.docx](https://file1.bdocx.com/fileroot1/2022-12/31/cd008953-b795-4523-b23b-df51d494cf57/cd008953-b795-4523-b23b-df51d494cf571.gif)
简单的DBMS
课程设计说明书
课程名称:
数据库系统课程设计
专业:
班级:
设计人:
学号:
2016年6月28日
课程设计任务书
一、课程设计题目:
简单的DBMS-对表的基本操作
二、设计原始资料:
1.《C程序设计(第三版)》,谭浩强主编,清华大学出版社
2.《数据库系统概论(第四版)》,王珊、萨师煊主编,高等教育出版社
三、设计应解决下列各主要问题:
1、实现:
以用户身份或游客身份进行该系统的登录,两种登录方式具有不同的权限。
2、实现:
进行表的创建并存储,包括表名、属性名、属性类型、NULL、主键。
3、实现:
显示所有数据表、属性信息、约束条件。
4、实现:
命令行操作,输入命令显示视图等。
5、SQL语句的简单解析。
四、设计说明书应附有下列图纸:
1.模块调用图(图1)
2.流程分析图(图2)
3.实现截图
五、小组分工说明:
六、命题发出日期:
2016.6.20 设计完成日期:
2016.6.24
指导教师评语
成绩:
指导教师(签章):
年 月 日
目录
1需求分析说明1
1.1设计要求1
1.2需求分析1
1.2.1功能需求分析1
1.3设计思路2
2概要设计说明2
2.1各功能模块功能描述2
2.2模块调用图3
2.3流程分析图4
3详细设计说明6
3.1主要结构6
3.2模块详细设计说明6
3.2.1用户登录模块6
3.2.2读写文件模块7
3.2.3创建表模块9
3.2.4修改表模块11
3.2.5命令行模块17
3.2.6存储数据模块18
4调试分析19
4.1验证读写用户名和密码文件——user.txt;passwd.txt19
4.2验证读写表信息文件——table.txt20
4.3验证读写表数据文件——date.txt21
4.4验证能否检测用户名和密码是否正确22
4.5验证能否检测主键拒绝设置空值23
4.6验证能否检测命令行模式命令输入错误24
5用户使用说明24
6课程设计总结26
1需求分析说明
1.1设计要求
(1)设计特定的数据结构,用于存储数据表、视图、索引等数据库对象的信息,即建立数据库系统的数据字典;
(2)设计特定的数据结构,用于存储数据表中的数据;
(3)设计特定的数据结构,用于存储索引数据;
(4)设计特定的数据结构,分别用于存储用户和访问权限的信息;
(5)输入“helpdatabase”命令,输出所有数据表、视图和索引的信息,同时显示其对象类型;输入“helptable表名”命令,输出数据表中所有属性的详细信息;输入“helpview视图名”命令,输出视图的定义语句;输入“helpindex索引名”命令,输出索引的详细信息;
(6)解析CREATE、SELECT、INSERT、DELETE、UPDATE等SQL语句的内容;
(7)检查SQL语句中的语法错误和语义错误;
(8)执行CREATE语句,创建数据表、视图、索引等数据库对象;创建数据表时需要包含主码、外码、唯一性约束、非空约束等完整性约束的定义;
(9)执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUPBY、HAVING和ORDERBY子句,需要支持5种聚集函数;
(10)执行INSERT、DELETE和UPDATE语句,更新数据表的内容;更新过程中需要检查更新后的数据表是否会违反参照完整性约束。
如果是,则提示违反哪一条完整性约束,并拒绝执行更新操作;如果否,提示数据表更新成功,并说明插入、删除或修改了几个元组。
(11)当数据表的内容更新后,根据索引的定义,自动更新索引表的内容;
(12)在有索引的数据表上执行查询语句时,首先利用索引找到满足条件的元组指针,然后通过指针到数据表中取出相应的元组;
(13)执行GRANT语句,为用户授予SELECT、INSERT、DELETE、UPDATE权限;执行REVOKE语句,收回上述权限;
(14)用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新操作,并给出提示信息;
(15)将SELECT语句转化为关系代数表达式,再利用查询优化算法对关系代数表达式进行优化,输出优化后的关系代数表达式或SELECT语句。
1.2需求分析
1.2.1功能需求分析
(1)用户登录
建立用户名和密码文档进行用户登录管理。
(2)表的创建
创建一个表,包含表名、属性名、属性类型、是否允许为空、是否为主键。
需要对表进行重复性检验以及选择合适的存储结构方便存取。
(3)表的修改
修改一个表的属性信息。
需要对修改进行合理性检验以及及时更新存储文件中的内容。
(4)数据存储
对一个表进行数据的存储。
需要对表进行数据存储,选择合适的存储结构方便对数据的存储和按属性查询。
(5)查询操作
用SQL语句或命令行模式对表的信息和数据进行查询操作,需要对所输入的SQL语句或命令进行解析并检测错误然后进行操作。
1.3设计思路
首先确定把表的信息和数据放在一个结构体中,用一个数组把他们联系起来。
表的信息存储在一个table.txt文件中,存储格式为:
表名
属性1名
属性类型
是否允许为空
是否为主键
属性2名
属性类型
是否允许为空
是否为主键
表的数据存储在date.txt文件中,存储格式为:
表名
属性1数据1;
属性2数据1;
属性3数据1
属性1数据2;
属性2数据2;
属性3数据2
读取表信息时按行读取文件内容即可,读取表数据时按行读取文件内容是通过检测“;”即可判断每一组数据的每个属性的数据间隔。
2概要设计说明
2.1各功能模块功能描述
(1)主函数模块
初始化图形界面、调用各功能模块。
(2)用户登录模块
检测是否第一次登录该系统,判断用户名和密码是否正确。
(3)读写table.txt模块
读写table.txt文件,进行表信息的更新。
(4)读写date.txt模块
读写date.txt文件,进行表中数据的更新。
(5)创建表模块
创建一个表,包含表名、属性名、属性类型、属性是否允许为空、属性是否为主键,并判断各名称是否重复以及NULL和主键冲突。
(6)修改表模块
修改已创建的表,并判断修改是否合法。
(7)存储数据模块
向一个已创建表中存储数据,并刷新到date.txt文件中。
(8)表信息显示模块
显示表的信息,包括表名、属性名、各属性的约束条件。
(9)表数据显示模块
显示表中具体数据。
(10)命令行操作模块
采用输入命令的方式来显示视图、表信息、表数据。
(11)SQL语句解析模块
对SQL语句进行简单解析并显示操作。
2.2模块调用图
(图一)
2.3流程分析图
(图二)
3详细设计说明
3.1主要结构
由于每一个表都有固定结构,所以建立一个表的结构体。
由于要进行数据的存储,为了方便,属性的数据数组charpro_date[10000][1000]也定义在表的结构体中。
typedefstruct
{
charpro_date[10000][1000];//属性的数据
intdate_num;//数据的组数
chartable_name[10];//表名
intpro_num;//属性的个数
charpro_name[10000][10];//属性名
intpro_type[1000];//属性类型(1代表int,2代表char)
intpro_null[100];//属性是否为空(1代表允许,2代表不允许)
intpro_key[100];//是否主码(1代表主键,2代表不是主键)
}TABLE;
定义TABLEtable[MAXN];把所有的表联系在一起。
3.2模块详细设计说明
3.2.1用户登录模块
首先判断用户是否为第一次登录,如果是第一次登录则进行新用户信息的存储,如果不是,则继续进行选择进行游客状态登录或用户登录并验证用户名和密码。
voidwelcome()//欢迎界面并判断是否为第一次登录
{
intx,y;
printf("______________________________________\n");
printf("|welcome!
|\n");
printf("||\n");
printf("|byzhaoxudong|\n");
printf("|1401061434|\n");
printf("______________________________________\n");
FILE*alfp1;
alfp1=fopen("user.txt","r");
if((alfp1=fopen("user.txt","r"))==NULL)
{
printf("这是您第一次使用本系统,游客登录->1\n");
printf("新建用户登录->2\n");
scanf("%d",&x);
if(x==2)
{
user();
}
elseif(x==1)
{
visit();
}
else
{
printf("输入错误!
!
!
\n");
}
}
else
{
printf("游客登录-->1\n用户登录-->2\n");
scanf("%d",&y);
if(y==2)
{
enter_user();
}
elseif(y==1)
{
visit();
}
else
{
printf("输入错误");
}
}
}
3.2.2读写文件模块
用户登录成功后首先调用读文件模块把表中已存储的数据读入到对应的数组中等待操作。
每当对表进行创建、修改、添加数据时,进行信息、数据的存储,表的信息存储在table.txt文件中,表的数据存储在date.txt文件中,由于防止文件中已存在的信息或数据对即将存储的信息或数据造成污染,采用存储信息或数据时把文件中所有数据进行刷新,即把数组中的所有信息重新写进文件。
voidread_txt()//读取table.txt
{
inti,j;
FILE*alfp1;
alfp1=fopen("table.txt","r");
fscanf(alfp1,"%d",&table_num);
for(i=0;i{
fscanf(alfp1,"%s",&table[i].table_name);
fscanf(alfp1,"%d",&table[i].pro_num);
for(j=0;j
{
fscanf(alfp1,"%s",&table[i].pro_name[j]);
fscanf(alfp1,"%d",&table[i].pro_type[j]);
fscanf(alfp1,"%d",&table[i].pro_null[j]);
fscanf(alfp1,"%d",&table[i].pro_key[j]);
}
}
fclose(alfp1);
}
voidwrite_txt()//写入table.txt
{
inti,j;
FILE*alfp1;
alfp1=fopen("table.txt","w");
fprintf(alfp1,"%d\n",table_num);
for(i=0;i{
fprintf(alfp1,"%s%d\n",table[i].table_name,table[i].pro_num);
for(j=0;j
fprintf(alfp1,"%s%d%d%d\n",table[i].pro_name[j],table[i].pro_type[j],
table[i].pro_null[j],table[i].pro_key[j]);
fprintf(alfp1,"\n");
}
fclose(alfp1);
}
voidwrite_date()//写数据进date.txt
{
inti,j;
FILE*alfp1;
alfp1=fopen("date.txt","w");
fprintf(alfp1,"%d\n",table_num);
for(i=0;i{
fprintf(alfp1,"%s%d\n",table[i].table_name,table[i].date_num);//表名和数据组数
for(j=0;j
fprintf(alfp1,"%s\n",table[i].pro_date[j]);
fprintf(alfp1,"\n");
}
fclose(alfp1);
}
3.2.3创建表模块
进行表的创建并存储,首先输入表名,检测表名是否重复,然后依次输入属性名以及各属性的类型、是否允许为空、是否为主键等信息,由于主键不允许为空,所以检测到一个属性被设置为允许为空并且是主键时,发出警告并强制该属性不能为空。
所有输入的信息均存储在对应的数组中,等待刷新到table.txt文件中。
voidcreatable()//创建表
{
inti,z,h;
charcreat_table_name[10];
intname_is_repeat=0;//表名是否重复,重复为1
printf("请输入表名:
");
scanf("%s",&creat_table_name);
for(i=0;i{
for(z=0;z<10;z++)
{
if(creat_table_name[z]==table[i].table_name[z])
{
name_is_repeat=1;
}
else
{
name_is_repeat=0;
break;
}
}
if(name_is_repeat==1)
{
printf("表名%s已经存在,请重新输入!
\n",creat_table_name);
menu();
}
else
{
break;
}
}
for(;;)//输入属性个数
{
printf("请输入表%s的属性个数:
",creat_table_name);
scanf("%d",&table[table_num].pro_num);
if(table[table_num].pro_num<=0)
{
printf("属性个数输入有误!
!
!
\n");
menu();
}
else
{
break;
}
}
for(h=0;h<10;h++)
{
table[table_num].table_name[h]=creat_table_name[h];//表名置换
}
for(i=0;i
{
printf("请输入表%s的%d个属性的具体信息:
\n",table[table_num].table_name,table[table_num].pro_num);
printf("表%s的%d个属性名称:
",creat_table_name,i+1);
scanf("%s",&table[table_num].pro_name[i]);//第i个属性的属性名称
printf("\n表%s的%d个属性类型(int为1,float为2):
",creat_table_name,i+1);
scanf("%d",&table[table_num].pro_type[i]);//第i个属性的属性类型printf("\n表%s的%d个属性是否允许为空(是为1,否为2):
",creat_table_name,i+1);
scanf("%d",&table[table_num].pro_null[i]);//第i个属性的属性是否允许为空printf("\n表%s的%d个属性是否为主键(是为1,否为2):
",creat_table_name,i+1);
scanf("%d",&table[table_num].pro_key[i]);//第i个属性的属性是否为主键if(table[table_num].pro_null[i]==1&&table[table_num].pro_key[i]==1)
{
printf("主键不允许为空!
!
!
");
table[table_num].pro_null[i]==0;
printf("属性%s已强制不为空!
!
!
",table[table_num].pro_name);
}
printf("\n");
}
table_num++;
write_txt();
printf("建表成功!
!
\n");
menu();
}
3.2.4修改表模块
首先进行表的检测,如果还没有创建一个表,发出警告并拒绝操作。
如果有多个表,首先选择一个要修改的表,选择修改表名、删除属性、添加属性、修改属性。
修改表名时检测新表名是否与已有表名重复,如果重复发出警报并拒绝操作。
删除属性即把该属性所对应的数组清空,等待刷新进table.txt文件。
添加属性即把该属性所有信息写入对应的数组等待刷新进table.txt文件。
修改属性时把要修改的属性内容写入新定义的change_pronum;//要修改的属性号、change_pro_xnum;//要修改的属性的项目号、charchange_pro_name[10];//要修改的属性的新名称、intchange_pro_type;//要修改的属性的新类型、intchange_pro_null;//要修改的属性是否为空、intchange_pro_key;//要修改的属性是否为主键中,等待检测没有重复等错误后把以上内容复制到该属性所对应的数组中等待刷新的到table.txt文件中。
voidchangetable()
{
inti;
intchoice_table;//选择表
intchoice_change;//选择项目
if(table_num==0)
{
printf("没有表可以修改!
\n");
menu();
}
else
{
printf("请选择要修改的表:
\n");
for(i=0;i{
printf("%s-->%d\n",table[i].table_name,i+1);
}
scanf("%d",&choice_table);
//判断表名是否正确
for(;;)
{
if(choice_table<0||choice_table>=table_num)
{
printf("输入错误!
!
");
menu();
}
else
{
break;
}
}
printf("请选择要修改表%s的项目:
修改表名-->1\n",table[choice_table].table_name);
printf(":
删除属性-->2\n");
printf(":
添加属性-->3\n");
printf(":
修改属性-->4\n");
scanf("%d",&choice_change);
switch(choice_change)
{
case1:
//修改表名
{
chartablename_new[10];
inttablename_flag;//检验表名是否存在
intp,k;
printf("请输入表%s的新表名:
",table[choice_table].table_name);
scanf("%s",tablename_new);
//判断新表名是否重复
for(k=0;k{
for(p=0;p<10;p++)
{
if(table[k].table_name[p]==tablename_new[p])
{
tablename_flag=1;
}
else
{
tablename_flag=0;
break;
}}
if(tablename_flag=1)
{
printf("新表名已存在!
!
\n");
menu();
}}
//名称替换
intn;
for(n=0;n<10;n++)
{
table[choice_table].table_name[n]=tablename_new[n];
}
write_txt();
printf("修改完成!
!
!
table.txt已更新!
!
!
\n");
menu();
break;
}
case2:
//删除属性
{
ints;
intchoice_pronum;//选择属性号
printf("表%s中的属性为:
",table[choice_table].table_name);
for(s=0;s