资源描述
课程设计说明书
课程名称: 数据库系统课程设计
专 业: 班级:
设 计 人:
学 号:
201年 7 月 24 日
课 程 设 计 任 务 书
一、 课程设计题目: 数据库课程设计
二、 设计原始资料: 《数据库系统概论》 王珊、萨师煊
《C++面向对象程序设计》
三、 设计应解决下列各主要问题:
1、设计特定的数据结构,用于存储数据表、视图、索引等数据库对象的信息,即建立数据库系统的数据字典;
2、设计特定的数据结构,用于存储数据表中的数据;
3、执行CREATE语句,创建数据表、视图、索引等数据库对象;创建数据表时需要包含主码、外码、唯一性约束、非空约束等完整性约束的定义;
4、执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUP BY、HAVING和ORDER BY子句,需要支持5种聚集函数;
5、用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新操作,并给出提示信息;
四、 设计说明书应附有下列图纸: 无
五、 小组分工说明: 无
六、命题发出日期: 2015-7-19 设计完成日期: 2015-7-26
指导教师评语
成绩:
指导教师(签章):
年 月 日
40
目 录
1需求分析说明 ………………………………………………………5
1.1课程设计的目的…………………………………………………………5
1.2课程设计的要求………………………………………………5
2 概要设计说明…………………………………………………… …………6
2.1 程序的数据结构…………………………………………………………6
2.2 模块调用图 ………………………………………………………………7
2.3DBMS程序模块的组成……………………… …………………………8
3 详细设计说明………………………………… ……………………………8
3.1主函数模块…………………………………………………………………8
3.2 用户登录检查………………………………………………………………8
3.3数据库,数据表的建立……………………………………………………9
3.4 SELECT语句的实现………………………………………………………11
3.5 UPDATE和DELETE语句的实现………………………………………13
4 调试分析…………………………………………………………14
5 用户使用说明………………………………………………………14
6 课程设计总结…………… …………………………… ………19
7源代码………………………………………19
1需求分析说明
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 users
{
private:
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 line[100];
int i=0,k=0;
while(FILE.getline(line,100))
{
s=line;
if(i%2==0)
u[k].n(s);
else if(i%2==1)
{
u[k].p(s);
k++;
}
i++;
}
FILE.close();
for(int j=0;j<k;j++)
{
if(name==u[j].n()&&pass==u[j].p())
return 1;
}
return 0;
}
3.3数据库,数据表的建立
本程序通过利用fstream文件流操作,实现了数据库和数据表的建立,但是对完整性约束的实现不是很成功。
void database::CreateTable() //建表
{
int sum=0;
char x;
char s1[10],s2[10],s3[10],s4[10];
int option;
string ShuxingName;//属性字符名
string Allpath2;
if(pathrecord=="0") //判断当前是否建立数据库
{
cout<<"ERROR!"<<endl<<"请先选择 1——>建立数据库"<<endl;
}
cout<<"请输入要建立的表名: "<<endl; //在建好数据库后建立表
cin>>TableName;
Allpath2=pathrecord+"shujuku.txt";
ofstream Tdfile2(Allpath2.c_str(),ios::app);
Allpath=pathrecord+TableName+".txt"; //库路径
a='y';
Tdfile2<<TableName<<endl;
Tdfile2.close();
while((a=='y')||(a=='Y'))
{
//文件打开,输入数据
ofstream Tdfile(Allpath.c_str(),ios::app);
ofstream Tdfile3(Allpath2.c_str(),ios::app); //输入信息流
cout<<"输入属性名称:"<<endl;
cin>>ShuxingName;
cout<<"输入属性类型:"<<endl;
cin>>LeixingName;
Tdfile<<ShuxingName<<",.\t"<<LeixingName<<":\t";
Tdfile3<<ShuxingName<<",.\t"<<LeixingName<<":\t"<<endl;
Tdfile3.close();
//检验属性类型,默认char和int和smallint
if((LeixingName=="char")|| (LeixingName=="CHAR"))
{
cout<<"请输入数据"<<endl;
sum++;
while(sum!=0)
{
cin>>TableShuju;
Tdfile<<TableShuju<<" ";
sum--;
if(sum==0)
{
Tdfile<<"\n";
Tdfile.close(); //文件流关闭
}
}
}
//判断int和smallint是否符合输入要求
else if((LeixingName=="smallint")|| (LeixingName=="SMALLINT") || (LeixingName=="INT")|| (LeixingName=="int"))
{
cout<<"请输入数据"<<endl;
sum++;
int shuju;
while(sum!=0)
{
cin>>shuju;
if((shuju>=0)&&(shuju<=1000))
{
Tdfile<<shuju<<" ";
sum--;
if(sum==0)
{
Tdfile<<"\n";
Tdfile.close(); //文件流关闭
}
}
}
}
cout<<"继续输入Y,停止输入N"<<endl;
cin>>a;
//在表内输入数据保证表数据完全
}
cout<<" 请依次输入主码、外码、唯一值、非空值,没有输入NULL"<<endl;
scanf("%s%s%s%s",s1,s2,s3,s4);
cout<<TableName<<"的主码是"<<s1<<endl;
cout<<TableName<<"的外码是"<<s2<<endl;
cout<<TableName<<"的唯一值是"<<s3<<endl;
cout<<TableName<<"的非空值是"<<s4<<endl;
}
3.4 SELECT语句的实现
本程序只实现了SELECT语句的单表查询,对连接查询,聚集函数等没有实现。
void database::select() //进行选择语句
{
string Table[MAX],shuxing[MAX],leixing[MAX],shuju[MAX];
string DatabaseName1,TableName1,Allpath1;
cout<<"请输入库名:"<<endl;
cin>>DatabaseName1;
cout<<"请输入表名:"<<endl;
cin>>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;
cout<<Allpath1<<"下的数据为:"<<endl;
ifstream file(Allpath1.c_str());
char line[MAX];
//读取每一行的数据
while(file.getline(line,MAX))
{
Table[i]=line;
cout<<"read line "<<i<<":"<<Table[i]<<endl;
i++;
}
sum=i;
for(j=0; j<i; j++)
{
k1=Table[j].find(',',0);
shuxing[j]=Table[j].substr(0,k1);
k2=Table[j].find(':',0);
leixing[j]=Table[j].substr(k1+2,k2-k1-2);
k3=Table[j].length();
shuju[j]=Table[j].substr(k2+1,k3-k2);
}
string xuanze;
int flag;
a='y';
//类似于之前的操作,在这个表中,全表遍历找出这个属性
while ((a=='y')||(a=='Y'))
{
flag=0;
i=0;
cout<<"请输入要选择的属性名:"<<endl;
cin>>xuanze;
while(i<sum)
{
if(strcmp(shuxing[i].c_str(),xuanze.c_str())==0)
{
cout<<"这个属性为:"<<shuxing[i]<<"数据为:"<<shuju[i]<<endl;
flag=1;
i++;
}
else if(strcmp(shuxing[i].c_str(),xuanze.c_str())!=0)
{
i++;
}
}
//使用标记flag来输出最后的结果
if(flag==1)cout<<"选择成功"<<endl;
if(flag==0)
cout<<"没有该属性"<<endl;
cout<<"是否继续选择其他的属性(y/n)"<<endl;
cin>>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 <iostream>
#include <string>
#include <fstream>
#include <windows.h>
#include <stdlib.h>
#include <cstdio>
#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 users
{
private:
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 u[100];
users person;
union Elemtype//定义元素类型
{
char CHAR; //字符型
char STRINR[MAX_STRING_LENGTH]; //字符串型
int INT;//整数型
double DOUBLE;//浮点型
};
struct Node//定义元素节点类型
{
union Elemtype arr[MAX_DATA_LEN];
struct Node *next;
};
struct Data//字段基本信息
{
char strName[MAX_NAME_LENTH]; //字段名
int nLen; //字段长度
char cType; //字段类型
};
struct DataNode//记录字段基本信息的节点
{
struct Data data;//字段基本信息结构体
struct DataNode *pNext;//指针
};
struct Table//记录所有字段信息的表结构体
{
int nLen;//表的长度
struct Data Head[MAX_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<<"请输入建立数据库名称: "<<endl;
cin>>DatabaseName;
path="d:\\\\"+DatabaseName; //路径=在D盘内,加上数据库的名字
pathrecord=path+"\\\\"; //全局记录路径
path="md "+path; //MD创建路径
system(path.c_str()); //把字符串转入命令
}
void database::CreateTable() //建表
{
int sum=0;
char x;
char s1[10],s2[10],s3[10],s4[10];
int option;
string ShuxingName;//属性字符名
string Allpath2;
if(pathrecord=="0") //判断当前是否建立数据库
{
cout<<"ERROR!"<<endl<<"请先选择 1——>建立数据库"<<endl;
}
cout<<"请输入要建立的表名: "<<endl; //在建好数据库后建立表
cin>>TableName;
Allpath2=pathrecord+"shujuku.txt";
ofstream Tdfile2(Allpath2.c_str(),ios::app);
Allpath=pathrecord+TableName+".txt"; //库路径
a='y';
Tdfile2<<TableName<<endl;
Tdfile2.close();
while((a=='y')||(a=='Y'))
{
//文件打开,输入数据
ofstream Tdfile(Allpath.c_str(),ios::app);
ofstream Tdfile3(Allpath2.c_str(),ios::app); //输入信息流
cout<<"输入属性名称:"<<endl;
cin>>ShuxingName;
cout<<"输入属性类型:"<<endl;
cin>>LeixingName;
Tdfile<<ShuxingName<<",.\t"<<LeixingName<<":\t";
Tdfile3<<ShuxingName<<",.\t"<<LeixingName<<":\t"<<endl;
Tdfile3.close();
//检验属性类型,默认char和int和smallint
if((LeixingName=="char")|| (LeixingName=="CHAR"))
{
cout<<"请输入数据"<<endl;
sum++;
while(sum!=0)
{
cin>>TableShuju;
Tdfile<<TableShuju<<" ";
sum--;
if(sum==0)
{
Tdfile<<"\n";
Tdfile.close(); //文件流关闭
}
}
}
//判断int和smallint是否符合输入要求
else if((LeixingName=="smallint")|| (LeixingName=="SMALLINT") || (LeixingName=="INT")|| (LeixingName=="int"))
{
cout<<"请输入数据"<<endl;
sum++;
int shuj
展开阅读全文