B -树索引的建立

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据库系统实现

实验报告

实验名称: B -树索引的建立

一、实验内容

使用B-树对数据库进行索引。按照学生ID建立起B树索引。实验需要建立两个文本文件:数据文件datafile.txt和命令文件command.txt。数据文件包含了所有需要建立检索的学生信息,文本中的每一行包含一个学生的信息。每一行将由6个空格分隔的字符段组成:ID (9位),姓(最多15个字符),名(最多

15个字符),年级(1位),专业(最多4个字符),以及邮箱地址(最多20个字符)。

二、实验分析:

三、步骤分析及流程图

步骤分析:一个具有10,000,000个记录的文本文件共计10,000,000*100B=1000MB,而内存只有50MB,50MB/4KB=50*1024 KB/4KB=12800块,每块可以存放4*1024B/100B=40个记录,每块剩余96KB,内存一共可以存放12800*40=512000个记录,一共有10,000,000个记录。

所以要进行10,000,000/512000=19.53次,即20次排序,每次排序的记录数为10,000,000/20=500,000个记录。

因此此次实验需要将文本文件分成20个子文件。分别对子文件分别进行内部排序。最后对20个排好序的子文件进行归并排序,完成排序。

故将其分为三个阶段

1.生成一个具有10,000,000个记录的文本文件data.txt,其中每个记

录由100个字节组成,其中只有一个整数类型属性A,剩余字节用0

填充。程序生成一个4个字节之内随机整数作为每条记录的属性,

剩余字节用0填充。记录写入data.txt文件中。

2.根据实验分析,将data.txt文件分为20个子文件,并且按照文件

中每个记录的属性对各个子文件进行内部排序,最终形成20个有序

的子文件data1.txt,data2,txt,…data20.txt。

3.对20个有序的子文件进行归并排序,最终形成一个有序的结果文件

result.txt。

流程图:

阶段一流程图见图1.1

图1.1 随机生成10,000,000个记录的文件流程图阶段二流程图见图1.2

图1.2 分离出20个内部有序的子文件流程图

阶段三流程图见图1.3

图1.3 将20个有序的子文件进行归并排序的流程图

四、算法优化

开始在阶段二,我们小组是利用自己写在类JL里的函数sort,采用选择序方法,运行后发现因为数据量大,产生速度特别慢。后来尝试用了快速排序,但是上网查了之后,发现调用java里面原有的排序函数速度更快。

五、实验中遇到的问题及解决

问题:函数produceResult()中我在写路径的时候,不小心多写了”/.txt”

而这个是通过编译的,却导致阶段三长时间运行不出来,开始还以为算法出了问题。

解决:将路径正确书写。

六、实验结果及分析

1.生成一个具有10,000,000个记录的文本文件xyj.txt。

2.将data.txt文件分为20个子文件,并且按照文件中每个记录的属性对

各个子文件进行内部排序,最终形成20个有序的子文件data0.txt,data1.txt,…data19.txt。这个阶段所用时间为46秒。

3.对20个有序的子文件进行归并排序,最终形成一个有序的结果文件

result.txt。所用时间为40秒。

4.按照教材cylinder-based buffers(1M bytes)的方法,修改第二阶段的

算法所得结果:

而为改进前的结果为

可见,第二阶段排序所用时间为46秒,比上次时间的7分46秒明显缩短,跟我们预期的结果一致。

七、实验小结

这次实验是我第一次和他人合作一起做一个程序,感觉沟通交流还是非常重要的,还有要花时间去理解他人的想法,这些都让我收获良多。至于阶段三的归并排序,因为此前已经在数据结构中用C++实现过,即使不太擅长java语言,还是能较快的做出来。通过这次实验,我了解了数据库中的大量数据的读取并没有想象中那么简单,在数据量多的时候,一个好的算法的作用是很大的,也更好的理解了归并排序在大文件排序中的作用和性能。

代码部分

BTree.h文件

#include

#include

#include

#include

#include

using namespace std;

#define m 3 //B树的阶即一个节点有3个键值,4个指针

//学生类

class Student

{

public:

string StudentId; //学生ID (9位)

string StudentFirstName; //姓(最多15个字符)

string StudentLastName; //名(最多15个字符)

int grade; //年级

(1位)

string Major; //专业(最多4个字符)

string email; //邮箱地址

(最多20个字符)

int Id; //int型

的学生id,便于节点处理

Student(){} //空的

构造函数

Student(string id, string firstn, string lastn, int grade, string major, string mail); //构造函数

};

//node类即B树中的一个节点

class Node

{

public:

int num; //一个节点对应的键值个数

int key[m + 1]; //一个节点键值,之所以+1,便于后面节点分裂

Node * ptr[m + 1]; //一个节点的指针数

Node * parent; //指向父节点的指针

Node(); //默认构造函数让所有值为空

Node(int number, int k[]); //构造函数初始化一个节点,它的键值为数组k的值,键值个数为number个

bool isLeafNode(Node * node);//判断是否为叶子节点

};

//Result结构体用在查询函数上

struct Result

{

Node * nptr; //对应数据键值所在节点的指针

int position; //对应数据键值在节点中的位置,从0开始算

bool tag; //该键值是否在节点中

};

//B树类

class BTree

{

public:

Result search( int id); //查找学生id(键值)

void insert1(int id); //添加数据键值函数1,即情况1:叶节点未满,插入数据后不用分裂节点

void insert2(Result a, int id); //添加数据键值函数2,即情况2:叶节点满,插入数据后需要分裂叶节点,但是内层节点还有空间不需要分裂

相关文档
最新文档