数据库课程设计,做完没多久,在这总结一下。(想哪写哪,看自己还能记得多少。)
系统由页面管理,记录管理,索引管理,系统处理,查询管理和语法分析等主要模块组成,页面管理,记录管理,语法分析模块老师已经帮我们完成了,我们只需要在此基础之上完成索引系统管理,查询处理和索引管理即可。
感觉真正复杂的在页面管理和记录管理,但是这两部分老师都给已经给我做好了,也就不用为难自己写了,直接调用函数即可,
整个数据库的操作流程:
1.数据的文件组成
数据是以文件形式保存的,都有若干页组成,所有操作均是以页为单位。每页大小为4k字节,这里可以自己设置,前四字节存放页号,后4092字节存放数据。
第0页是分页信息控制页,在该页页号之后有个保存有分页头信息的结构体,头信息中含有尾页的页号,已经分配的页数,之后存放一个位图,保存各个页的分配情况,0代表未分配,1代表已分配。这个分页文件的页数受位图的限制。
第1页为记录信息控制页,在该页页号之后也存有一个保存有记录头信息的结构体,头信息包含有当前文件包含的记录数,每个记录的大小,一个分页可以装载的记录数,第一个记录的偏移值,之后也存放一个位图,但是和分页控制页不同的是,这里的位图标志的是每一页是否为满,1表示满,0表示未满。
从第2页开始为数据页,记录在数据页采用顺序存储的形式,在一个记录文件中可以通过页号和插槽号来定位记录,在每个数据页,在页号之后存放一个位图存放的每个插槽的占用情况,1代表占用,0代表未占用。
2.系统管理模块
每个database对应一个系统表文件,一个系统列文件和若干数据文件。
系统表文件包含有:表名占21个字节,即表名的最大长度为20个字节。表中属性的数量占用sizeof(int)共4个字节。
表名 tablename | 该表中属性的数量 attrcount |
tablename | attrname | attrtype | attrlength | attroffset | ix_flag | indexname |
系统管理模块主要是对系统列和系统表文件的读写来实现管理的。
2.1创建数据库:
实现:创建一个名字为dbtest的文件夹,并在文件夹中新建两个记录文件。一个系统表文件SYSTABLES,一个系统列文件SYSCOLUMNS。
2.2删除数据库
实现:递归i删除整个文件。
2.3打开数据库
调用老师的接口来实现的,不说了
2.4建表
sql语句:create table s(sno int,sname char(8));
create table c(cno int,cname char(8));
create table sc(sno int,cno int,score float);
函数接口:RC CreateTable (char*relName, int attrCount, AttrInfo *attributes)
实现: 调用语法分析模块将sql语句的各信息赋给下边的结构体。
//struct of craete_table
typedef struct {
char *relName; //要创建的表的表名
int attrCount; //表中属性的数量
AttrInfo attributes[MAX_NUM]; //属性的信息
}createTable;
1.打开系统表和系统列文件,根据系统表和系统列的结构体填充相应信息,同时计算一条记录的长度,然后关闭文件
2.根据获得的记录大小创建名为relName的记录文件。
2.5删表
sql语句: drop table s;
函数接口:RC DropTable(char *relName)
实现:
//struct of drop_table
typedef struct {
char *relName; //要删除的表的表名
}dropTable;
1.删除对应的文件2.打开系统表和系统列文件,首先读取系统表文件,获取表的属性数量,然后删除系统表中该记录
3.读取系统系统列文件,匹配表名,找到第一条记录,然后删除该表对应数量的记录,然后关闭文件。
2.6插入
sql语句:insert into s values(1,‘lcj’);
insert into c values(1,'db');
insert into sc values(1,1,98.0);
函数接口: RC Insert (char *relName,int nValues, Value *values)
实现:
//struct of insert
typedef struct {
char *relName; //要插入记录的表名
int nValues; //插入的值的数量
Value values[MAX_NUM]; //要插入的值
}inserts;
1.打开系统表和系统列文件,读取对应表的相关信息
2.根据这些信息向对应的数据表中插入数据,类似于建表时向系统表和系统列填充信息
只不过系统表和系统列各条记录的数据结构是固定的,这里的需要根据sql语句来确定。
2.7删除(条件不支持or)
sql语句:delete from c where c.cno = 1;
delete from sc where sc.sno = 1 and sc.cno = 1
函数接口:RC Delete(char *relName, int nConditions, Condition *conditions)
实现:
//struct of delete
typedef struct {
char *relName; //要删除记录的表名
int nConditions; //where子句中条件的数量
Condition conditions[MAX_NUM]; //where子句中的条件
}deletes;
1.打开系统表和系统列文件,读取对应表的相关信息
2.两层循环逐一读取数据表中数据,然后循环nConditions次,逐一判断各个条件是否成立(只支持and)
3.如果各个条件均满足,则删除该记录。
2.8更新(单值更新,条件不支持or)
sql语句:update s set sno = 2 where sno = 1;
update sc set score = 100.0 where sc.sno = 1 and sc.cno = 1;
函数接口:RC Update(char *relName, char *attrName, Value *Value, int nConditions, Condition *conditions)
实现:
//struct of update
typedef struct {
char *relName; //要修改记录的表名
char *attrName; //要修改的属性名
Value value; //修改成的值
int nConditions; //where子句中条件的数量
Condition conditions[MAX_NUM]; // where子句中的条件
}updates;
跟delete类似,不赘述。
2.9查询(支持多表连接查询)
sql语句:select s.sname,c.cname,sc.score from s,c,sc where s.sno = sc.sno and c.cno = sc.cno and c.cno = 1;
函数接口:RC Select(int nSelAttrs, RelAttr **selAttrs, int nRelations, char ** relations,int nConditions, Condition *conditions, char **RES)
实现:(这个应该是系统管理模块里边最复杂的一个)
//struct of select
typedef struct {
int nSelAttrs; //select子句中属性的数量
RelAttr *selAttrs[MAX_NUM]; //select子句中的属性
int nRelations; //from子句中表的数量
char *relations[MAX_NUM]; //from子句中的表
int nConditions; //where子句中条件的数量
Conditionconditions[MAX_NUM];//where子句中的条件
}selects;
1.打开数据表,系统表,系统列文件,读取该表相应信息,2.做笛卡尔积,还要获取要查询的属性在笛卡尔积的位置保留在一个结构体中
typedef struct printrel{
int i; //保存属性对应表名对应的下标
SysColumn col;//保存属性信息
}printrel;
3.笛卡儿积逐一进行判断,对条件逐一判断,如果满足条件,写入data中。
4.data的数据结构是,开始要显示的行数和列数,以及记录数,接下来存的是要显示的一条一条记录,记录的大小我们固定为20*属性数量。
2.10索引待续。