From 63faaf68f98cbebff168bc0234de3e72034fda9a Mon Sep 17 00:00:00 2001 From: StarDust <375670450@qq.com> Date: Mon, 20 Jun 2016 22:23:04 +0800 Subject: [PATCH 1/2] update readme.md --- MicroSQL.vcxproj | 1 + MicroSQL.vcxproj.filters | 3 + README.docx | Bin 0 -> 13631 bytes README.md | 179 +++++++++++++++----- src/IndexScan.hpp | 13 +- src/Printer.hpp | 347 +++++++++++++++++++++++++++++++++++++++ src/QueryManager.hpp | 42 +++++ src/SystemManager.hpp | 3 + src/Utils.hpp | 17 +- 9 files changed, 555 insertions(+), 50 deletions(-) create mode 100644 README.docx create mode 100644 src/Printer.hpp diff --git a/MicroSQL.vcxproj b/MicroSQL.vcxproj index c5e2905..a9aeaea 100644 --- a/MicroSQL.vcxproj +++ b/MicroSQL.vcxproj @@ -27,6 +27,7 @@ + diff --git a/MicroSQL.vcxproj.filters b/MicroSQL.vcxproj.filters index afb7ee4..80ea2e4 100644 --- a/MicroSQL.vcxproj.filters +++ b/MicroSQL.vcxproj.filters @@ -95,5 +95,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/README.docx b/README.docx new file mode 100644 index 0000000000000000000000000000000000000000..c920d307a73d361fc1ada386049333c2fa568b94 GIT binary patch literal 13631 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 注: -> 1. 每个页面的大小(字节)用PF_PAGE_SIZE表示, 默认为4K (4096字节) -> 2. 内存池中的页面数用PF_BUFFER_SIZE表示, 默认为40 -> 3. 所有作为存储函数返回结果的指针传进来时应保证其原来的数据(如果有的话)已经无需再使用了 - - -##RecordManager -RM模块提供的类和方法用于把记录存储在文件中, 相当于PF模块的客户端. 在这个模块中需要调用PF模块中已经实现的函数. - -###文件头 -为了便于管理文件内容, 可以把每个文件的第一个Page作为一个特殊的Header Page, 用于存储空闲空间的信息, 文件存储的记录数, 每个页面存储的记录数, 文件的当前页面数以及其他与整个文件有关的信息. 每个页面也包含一个页面头. - -###记录标识符 -RecordIdentifier类对一个指定文件中的所有记录提供唯一标识, 因此一条指定记录的标识符应该是保持不变的. 即一个标识符的属性在记录更新或其他记录插入/删除的条件下都是恒定的. 每个文件的页面有数量不等的Slot(根据每个文件的Record的大小确定), 但一个文件内的所有页面Slot数相同. 在这个系统中只用页面号(PageNum)以及槽号(SlotNum)来构成为RecordIdentifier. - -###记录空闲空间 -当需要插入记录时, 不应该线性搜索有空余的页面. 为了提高搜索效率, 可以使用一个页的链表来存储有空余Slot的页面. - - -每个文件中存储的记录必须是等长的, 这样能更方便地管理每个页面上的记录和空闲空间, 而且保证了每个记录的位置都能够方便地访问到. 最好每个表单独存储在一个文件中. - - + +# MicroSQL 开发文档 + +---------------------------- + +##一. 总体框架 + +#### 1.1 概述 + +MicroSQL是一个轻量级的关系型数据库, 框架的设计思路主要根据斯坦福大学的[Database System Implementation(CS346)](https://web.stanford.edu/class/cs346/2015/)课程提供的Redbase数据库框架来设计. +主要包含5个模块: + - PageFile(PF) + - RecordManager(RM) + - IndexManager(IX) + - SystemManager(SM) + - QueryManager(QM) + 在具体的实现中, 为了遵循模块化程序设计的原则, 将各个模块按照不同的功能分成多个类来实现, 具体实现细节将在后面介绍 + +#### 1.2 层次结构 + +#### 1.3 基本功能 + - 支持的数据类型: INT, FLOAT, STRING(需要指定大小). + - 数据库的建立和删除,以及数据库的统计信息查询 + - 表的建立和删除,以及表的统计信息查询 + - 索引的建立和删除 + - 使用与MySQL语法相似的SQL语句对表或数据库中的数据执行增、删、改、查操作 + +#### 1.4 设计语言和运行环境 +开发环境:Visual Studio 2015 +编程语言:C++(主要使用C++11推荐语法) + +## 二. 各模块的具体功能 +#### 2.1 Page File Manager(PF) +PF模块是系统的最底层模块, 主要向高层次的结构(Index Manager和Record Manager)提供以页为基本单元的文件IO操作. 在该模块中, 主要实现了创建, 删除, 打开和关闭文件四个操作. +对于单个文件(PageFile类)的操作, 必须先从PF模块打开一个PageFile实例为操作对象, 以页(Page)为最小访问单元. PageFile提供了从文件中获取一个新的Page, 获取一个特定页号的Page, 强制更新(Force)文件中特定页号的Page等方法. +实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page. + +#### 2.2 Record Manager(RM) +RM模块是管理记录文件的模块, 主要面向Query Manager和System Manager两个模块. RM模块只提供了对记录文件的创建, 删除, 打开和关闭四个操作. +在MicroSQL的实现中, 每个表中有若干条记录, 一个表中的所有记录必须存在同一个记录文件(RecordFile)中. 对单个记录文件的操作, 必须通过RecordFile实例进行操作. RecordFile提供了对该文件中记录的增删改查四个操作. + +#### 2.3 Index Manager(IX) +IX模块是管理索引的模块, 主要提供了对某个表的属性进行创建, 删除索引, 并对已创建的索引的打开, 关闭四个操作. 关于索引的具体实现, MicroSQL的索引与大多数数据库引擎类似, 使用B+树作为索引的数据结构, 每个B+树的结点存储在一个Page中, 以达到较高的索引效率. +其他模块对于单个索引的数据插入, 删除, 查询, 必须先通过Index Manager获取一个IndexHandle实例, 并通过这个IndexHandle实例进行操作. + +#### 2.4 System Manager(SM) +SM模块直接面向Command Parser,提供一些可能会影响整个数据库系统的操作,包括: + + - 创建、删除一个数据库/关系表/索引等(DDL) + - 维护系统中各个数据库和表的Catalog + - 从文件中导入数据 + - 设置数据库或表的参数 + - 输出关系表 + +#### 2.5 Query Manager(QM) +QM模块与SM模块类似,主要向Command Parser提供了用于执行特定的SQL操作。当前的实现支持的SQL操作有Select(包括多表联查),Insert,Delete,Update四种操作。操作的执行主要先通过System Manager获取查询表的结构, 分析后通过调用Record Manager的方法查询并解析查询的结果, 返回给Command Parser. + + +## 三. 重要接口 + +#### 2.1 Page File Manager(PF) +`RETCODE CreateFile (const char * fileName); // Create a new file` +创建一个新的文件(索引的结点或是记录文件) + +`RETCODE DestroyFile (const char * fileName); // Destroy a file` +删除一个文件 + +`RETCODE OpenFile (const char * fileName, PageFilePtr & fileHandle); // Open a file` + + +`RETCODE CloseFile (PageFilePtr &fileHandle); // Close a file` + +#### 2.2 Record Manager(RM) + +#### 2.3 Index Manager(IX) + +#### 2.4 System Manager(SM) + +#### 2.5 Query Manager(QM) + + + +## 四. 使用语法 + +## 五. 实际测试 + + +## 六. 组内分工 + + + +##Page/PageFile + +PF模块中除了构造函数与析构函数之外的每个函数都返回一个整数. 返回值为0表示正常完成. 所有非0返回值均暗示了有异常情况或错误发生. 返回值为正数表示遇到异常(比如读到文件尾或关闭一个未打开的文件等对程序影响不大的错误); 返回值为负表示发生了系统无法自动处理的错误. + +###页缓冲池 +获取一个文件中某页面上的数据需要先把页面存入缓冲池(维护在内存中), 然后在缓冲池中操作(读写)数据. 当一个内存中的页面和数据正在被操作时, 必须先将页面的状态设为locked (固定). 当某个进程对页面的所有操作均结束后, 必须立即把页面状态改为unlocked, 但此时并不需要把页面移出缓冲池. +只有当需要读一个新的页, 并且缓冲池中的内存不足时才会选择一个unlocked的页面移出. 所使用的选择算法为Least-Recently-Used (LRU). 当一个页面被移出缓冲池时, 只有该页面被标记为dirty才会将硬盘上页面对应的文件重写以更新页面文件, 即非dirty的页面被移出缓冲池时不需要做任何工作. 但也提供了接口使得PF模块可以强制将一个非dirty的页面数据写入硬盘, 以及在不移出页面的情况下将所有在缓冲池中的dirty页面的数据写入硬盘. +PageManager必须保证每个页面只能同时被一个事务使用, 即一个locked状态下的页面不能被locked. + +###页面号 +一个文件中的页面需要用页面号标识, 页面号对应其在文件中的位置. 当新建一个文件并分配页面时, 页面号是顺序增长的. 但一个页面被删除之后, 新分配的页面其页面号不一定是顺序的, 而是在之前分配过的页面上寻找一个最近被删除的页面(用栈存储删除的页面号)来存放该页面数据. 若栈为空时才在之前的页面之后再分配一个新的页面. + +------------------------ + +> 注: +> 1. 每个页面的大小(字节)用PF_PAGE_SIZE表示, 默认为4K (4096字节) +> 2. 内存池中的页面数用PF_BUFFER_SIZE表示, 默认为40 +> 3. 所有作为存储函数返回结果的指针传进来时应保证其原来的数据(如果有的话)已经无需再使用了 + + +##RecordManager +RM模块提供的类和方法用于把记录存储在文件中, 相当于PF模块的客户端. 在这个模块中需要调用PF模块中已经实现的函数. + +###文件头 +为了便于管理文件内容, 可以把每个文件的第一个Page作为一个特殊的Header Page, 用于存储空闲空间的信息, 文件存储的记录数, 每个页面存储的记录数, 文件的当前页面数以及其他与整个文件有关的信息. 每个页面也包含一个页面头. + +###记录标识符 +RecordIdentifier类对一个指定文件中的所有记录提供唯一标识, 因此一条指定记录的标识符应该是保持不变的. 即一个标识符的属性在记录更新或其他记录插入/删除的条件下都是恒定的. 每个文件的页面有数量不等的Slot(根据每个文件的Record的大小确定), 但一个文件内的所有页面Slot数相同. 在这个系统中只用页面号(PageNum)以及槽号(SlotNum)来构成为RecordIdentifier. + +###记录空闲空间 +当需要插入记录时, 不应该线性搜索有空余的页面. 为了提高搜索效率, 可以使用一个页的链表来存储有空余Slot的页面. + + +每个文件中存储的记录必须是等长的, 这样能更方便地管理每个页面上的记录和空闲空间, 而且保证了每个记录的位置都能够方便地访问到. 最好每个表单独存储在一个文件中. + + +###访问记录 +当主程序需要访问表Table中一条标识符为Id的记录时, 分两个步骤: 首先通过RecordManager->OpenFile(Table)申请一个RecordFile(实际上, 只能通过这个类来访问数据库的记录), 通过RecordFile->GetRec(Id)来获取一个Record对象. +但是由于这样效率比较低下, 因此主要还是用FileScan类来让客户端与数据库进行交互 + +##Index Manager + + +##System Manager + + +##Query Manager diff --git a/src/IndexScan.hpp b/src/IndexScan.hpp index d423f88..96baf04 100644 --- a/src/IndexScan.hpp +++ b/src/IndexScan.hpp @@ -19,7 +19,6 @@ class IndexScan { private: - //std::vector<> }; @@ -28,3 +27,15 @@ IndexScan::IndexScan ( ) { IndexScan::~IndexScan ( ) { } + +inline RETCODE IndexScan::OpenScan (const IndexHandle & indexHandle, CompOp compOp, void * value) { + +} + +inline RETCODE IndexScan::GetNextEntry (RecordIdentifier & rid) { + return RETCODE ( ); +} + +inline RETCODE IndexScan::CloseScan ( ) { + return RETCODE ( ); +} diff --git a/src/Printer.hpp b/src/Printer.hpp new file mode 100644 index 0000000..0eaac3e --- /dev/null +++ b/src/Printer.hpp @@ -0,0 +1,347 @@ +#pragma once + +#include "Utils.hpp" +#include +#include +#include +#include + +#ifndef mmin +#define mmin(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef mmax +#define mmax(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +const int MAXPRINTSTRING = ( 2 * Utils::MAXNAMELEN) + 5; + +// Print some number of spaces +void Spaces (int maxLength, int printedSoFar); + +struct DataAttrInfo; +class Tuple; + +class Printer { +public: + // Constructor. Takes as arguments an array of attributes along with + // the length of the array. + Printer (const DataAttrInfo *attributes, const int attrCount); + Printer (const Tuple& t); + + ~Printer ( ); + + void PrintHeader (std::ostream &c) const; + + // Two flavors for the Print routine. The first takes a char* to the + // data and is useful when the data corresponds to a single record in + // a table -- since in this situation you can just send in the + // RecData. The second will be useful in the QL layer. + void Print (std::ostream &c, const char * const data); + void Print (std::ostream &c, const void * const data[]); + void Print (std::ostream &c, const Tuple& t); + + void PrintFooter (std::ostream &c) const; + +private: + void Init (const DataAttrInfo *attributes_, const int attrCount_); + +private: + DataAttrInfo *attributes; + int attrCount; + + // An array of strings for the header information + char **psHeader; + // Number of spaces between each attribute + int *spaces; + + // The number of tuples printed + int iCount; +}; + + +// +// printer.cc +// + +// This file contains the interface for the Printer class and some +// functions that will be used by both the SM and QL components. + +#include +#include +#include +#include "printer.hpp" + +using namespace std; + +// +// void Spaces(int maxLength, int printedSoFar) +// +// This method will output some spaces so that print entry will align everythin +// nice and neat. +// +void Spaces (int maxLength, int printedSoFar) { + for ( int i = printedSoFar; i < maxLength; i++ ) + std::cout << " "; +} + +// +// ------------------------------------------------------------------------------ +// +Printer::Printer (const Tuple& t) { + Init (t.GetAttributes ( ), t.GetAttrCount ( )); +} + +// +// Printer +// +// This class handles the printing of tuples. +// +// DataAttrInfo - describes all of the attributes. Defined +// within sm.h +// attrCount - the number of attributes +// +Printer::Printer (const DataAttrInfo *attributes_, const int attrCount_) { + Init (attributes_, attrCount_); +} + +void Printer::Init (const DataAttrInfo *attributes_, const int attrCount_) { + attrCount = attrCount_; + attributes = new DataAttrInfo[attrCount]; + + for ( int i = 0; i < attrCount; i++ ) { + attributes[i] = attributes_[i]; + // std::cout << "Printer::init i, offset " << attributes[i].offset << endl; + } + // Number of tuples printed + iCount = 0; + + // Figure out what the header information will look like. Normally, + // we can just use the attribute name, but if that appears more than + // once, then we should use "relation.attribute". + + // this line broke when using CC + // changing to use malloc and free instead of new and delete + // psHeader = (char **) new (char *)[attrCount]; + psHeader = ( char** ) malloc (attrCount * sizeof (char*)); + + // Also figure out the number of spaces between each attribute + spaces = new int[attrCount]; + + for ( int i = 0; i < attrCount; i++ ) { + // Try to find the attribute in another column + int bFound = 0; + psHeader[i] = new char[MAXPRINTSTRING]; + memset (psHeader[i], 0, MAXPRINTSTRING); + + for ( int j = 0; j < attrCount; j++ ) + if ( j != i && + strcmp (attributes[i].attrName, + attributes[j].attrName) == 0 ) { + bFound = 1; + break; + } + + if ( bFound ) + sprintf_s (psHeader[i], MAXPRINTSTRING,"%s.%s", + attributes[i].relName, attributes[i].attrName); + else + strcpy_s (psHeader[i], MAXPRINTSTRING, attributes[i].attrName); + + if ( attributes[i].attrType == STRING ) + spaces[i] = mmin (attributes[i].attrLength, MAXPRINTSTRING); + else + spaces[i] = mmax (12, strlen (psHeader[i])); + + // We must subtract out those characters that will be for the + // header. + spaces[i] -= strlen (psHeader[i]); + + // If there are negative (or zero) spaces, then insert a single + // space. + if ( spaces[i] < 1 ) { + // The psHeader will give us the space we need + spaces[i] = 0; + strcat_s (psHeader[i], MAXPRINTSTRING," "); + } + } +} + + +// +// Destructor +// +Printer::~Printer ( ) { + for ( int i = 0; i < attrCount; i++ ) + delete[] psHeader[i]; + + delete[] spaces; + //delete [] psHeader; + free (psHeader); + delete[] attributes; +} + +// +// PrintHeader +// +void Printer::PrintHeader (std::ostream &c) const { + int dashes = 0; + int iLen; + int i, j; + + for ( i = 0; i < attrCount; i++ ) { + // Print out the header information name + c << psHeader[i]; + iLen = strlen (psHeader[i]); + dashes += iLen; + + for ( j = 0; j < spaces[i]; j++ ) + c << " "; + + dashes += spaces[i]; + } + + c << "\n"; + for ( i = 0; i < dashes; i++ ) c << "-"; + c << "\n"; +} + +// +// PrintFooter +// +void Printer::PrintFooter (std::ostream &c) const { + c << "\n"; + c << iCount << " tuple(s).\n"; +} + +// +// Print +// +// data - this is an array of void *. This print routine is used by +// the QL Layer. +// +// Unfortunately, this is essentially the same as the other Print +// routine. +// +void Printer::Print (std::ostream &c, const void * const data[]) { + char str[MAXPRINTSTRING], strSpace[50]; + int i, a; + float b; + + // Increment the number of tuples printed + iCount++; + + for ( i = 0; iMAXPRINTSTRING ) { + strcpy_s (str, MAXPRINTSTRING - 1, ( char * ) data[i]); + str[MAXPRINTSTRING - 3] = '.'; + str[MAXPRINTSTRING - 2] = '.'; + c << str; + Spaces (MAXPRINTSTRING, strlen (str)); + } else { + strcpy_s (str, attributes[i].attrLength, ( char * ) data[i]); + c << str; + if ( attributes[i].attrLength < ( int ) strlen (psHeader[i]) ) + Spaces (strlen (psHeader[i]), strlen (str)); + else + Spaces (attributes[i].attrLength, strlen (str)); + } + } + if ( attributes[i].attrType == INT ) { + memcpy (&a, data[i], sizeof (int)); + sprintf_s (strSpace, MAXPRINTSTRING,"%d", a); + c << a; + if ( strlen (psHeader[i]) < 12 ) + Spaces (12, strlen (strSpace)); + else + Spaces (strlen (psHeader[i]), strlen (strSpace)); + } + if ( attributes[i].attrType == FLOAT ) { + memcpy (&b, data[i], sizeof (float)); + sprintf_s (strSpace, MAXPRINTSTRING,"%f", b); + c << strSpace; + if ( strlen (psHeader[i]) < 12 ) + Spaces (12, strlen (strSpace)); + else + Spaces (strlen (psHeader[i]), strlen (strSpace)); + } + } + c << "\n"; +} + +void Printer::Print (std::ostream &c, const Tuple& t) { + const char * data; + t.GetData (data); + // std::cout << "Printer::Print(tuple) " << t << endl; + Print (c, data); +} + +// +// Print +// +// data - the actual data for the tuple to be printed +// +// The routine tries to make things line up nice, however no +// attempt is made to keep the tuple constrained to some number of +// characters. +// +void Printer::Print (std::ostream &c, const char * const data) { + char str[MAXPRINTSTRING], strSpace[50]; + int i, a; + float b; + + if ( data == NULL ) + return; + + // Increment the number of tuples printed + iCount++; + + for ( i = 0; iMAXPRINTSTRING ) { + strcpy_s (str, MAXPRINTSTRING - 1, data + attributes[i].offset); + str[MAXPRINTSTRING - 3] = '.'; + str[MAXPRINTSTRING - 2] = '.'; + c << str; + Spaces (MAXPRINTSTRING, strlen (str)); + } else { + strcpy_s (str, attributes[i].attrLength, data + attributes[i].offset); + c << str; + if ( attributes[i].attrLength < ( int ) strlen (psHeader[i]) ) + Spaces (strlen (psHeader[i]), strlen (str)); + else + Spaces (attributes[i].attrLength, strlen (str)); + } + } + if ( attributes[i].attrType == INT ) { + memcpy (&a, ( data + attributes[i].offset ), sizeof (int)); + sprintf_s (strSpace, MAXPRINTSTRING,"%d", a); + c << a; + if ( strlen (psHeader[i]) < 12 ) + Spaces (12, strlen (strSpace)); + else + Spaces (strlen (psHeader[i]), strlen (strSpace)); + } + if ( attributes[i].attrType == FLOAT ) { + memcpy (&b, ( data + attributes[i].offset ), sizeof (float)); + sprintf_s (strSpace, MAXPRINTSTRING, "%f", b); + c << strSpace; + if ( strlen (psHeader[i]) < 12 ) + Spaces (12, strlen (strSpace)); + else + Spaces (strlen (psHeader[i]), strlen (strSpace)); + } + } + c << "\n"; +} diff --git a/src/QueryManager.hpp b/src/QueryManager.hpp index f816c85..b9e759f 100644 --- a/src/QueryManager.hpp +++ b/src/QueryManager.hpp @@ -6,6 +6,7 @@ #include "Utils.hpp" #include "Iterator.hpp" +#include "Printer.hpp" #include "RecordFile.hpp" #include "SystemManager.hpp" #include "IndexManager.hpp" @@ -101,6 +102,47 @@ inline RETCODE QueryManager::Select (int nSelAttrs, const RelAttr selAttrs[], in inline RETCODE QueryManager::Insert (const char * relName, int nValues, const Value values[]) { + RETCODE rc = smm->SemCheck (relName); + if ( rc != 0 ) return rc; + + int attrCount; + DataAttrInfo* attr; + rc = smm->GetFromTable (relName, attrCount, attr); + + if ( nValues != attrCount ) { + delete[] attr; + return RETCODE::INVALIDINSERT; + } + + int size = 0; + for ( int i = 0; i < nValues; i++ ) { + if ( values[i].type != attr[i].attrType ) { + delete[] attr; + return RETCODE::TYPEMISMATCH; + } + size += attr[i].attrLength; + } + + char * buf = new char[size]; + int offset = 0; + for ( int i = 0; i < nValues; i++ ) { + assert (values[i].data != NULL); + memcpy (buf + offset, + values[i].data, + attr[i].attrLength); + offset += attr[i].attrLength; + } + + rc = smm->LoadRecord (relName, size, buf); + if ( rc != 0 ) return rc; + + Printer p (attr, attrCount); + p.PrintHeader (cout); + p.Print (cout, buf); + p.PrintFooter (cout); + + delete[] attr; + delete[] buf; return RETCODE::COMPLETE; diff --git a/src/SystemManager.hpp b/src/SystemManager.hpp index 95c70a4..c672a66 100644 --- a/src/SystemManager.hpp +++ b/src/SystemManager.hpp @@ -13,6 +13,9 @@ #include class SystemManager { + + friend class QueryManager; + public: SystemManager (const IndexManagerPtr & ixm, const RecordFileManagerPtr & rm); diff --git a/src/Utils.hpp b/src/Utils.hpp index fa4ac5b..864a9ed 100644 --- a/src/Utils.hpp +++ b/src/Utils.hpp @@ -8,14 +8,14 @@ #include #include #include - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif /* @@ -97,6 +97,7 @@ enum RETCODE { TYPEMISMATCH, ENTRYNOTFOUND, BADOP, + INVALIDINSERT, }; enum AttrType { From 4300a2fd2b737849f0df190d7397993431ba86c5 Mon Sep 17 00:00:00 2001 From: StarDust <375670450@qq.com> Date: Mon, 20 Jun 2016 22:56:04 +0800 Subject: [PATCH 2/2] update readme 20-22:55 --- README.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 67080de..af48ebb 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ MicroSQL是一个轻量级的关系型数据库, 框架的设计思路主要根 #### 2.1 Page File Manager(PF) PF模块是系统的最底层模块, 主要向高层次的结构(Index Manager和Record Manager)提供以页为基本单元的文件IO操作. 在该模块中, 主要实现了创建, 删除, 打开和关闭文件四个操作. 对于单个文件(PageFile类)的操作, 必须先从PF模块打开一个PageFile实例为操作对象, 以页(Page)为最小访问单元. PageFile提供了从文件中获取一个新的Page, 获取一个特定页号的Page, 强制更新(Force)文件中特定页号的Page等方法. -实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page. +实际上, 由于文件系统IO速度比较慢, 为了提高获取数据的速度, PM模块还需要对每个文件维护一个Buffer(BufferManager类). 每个BufferManager实例管理一个PageFile实例以及一个Buffer(用哈希表结构存储在内存中), 上层模块只能通过BufferManager来间接地访问PageFile获取所需Page. #### 2.2 Record Manager(RM) RM模块是管理记录文件的模块, 主要面向Query Manager和System Manager两个模块. RM模块只提供了对记录文件的创建, 删除, 打开和关闭四个操作. @@ -58,7 +58,9 @@ QM模块与SM模块类似,主要向Command Parser提供了用于执行特定 ## 三. 重要接口 -#### 2.1 Page File Manager(PF) +### 2.1 PF模块 +#### PageManager类 + `RETCODE CreateFile (const char * fileName); // Create a new file` 创建一个新的文件(索引的结点或是记录文件) @@ -66,21 +68,122 @@ QM模块与SM模块类似,主要向Command Parser提供了用于执行特定 删除一个文件 `RETCODE OpenFile (const char * fileName, PageFilePtr & fileHandle); // Open a file` - +打开一个文件并获取该文件的PageFile实例 `RETCODE CloseFile (PageFilePtr &fileHandle); // Close a file` +关闭一个文件并释放PageFile实例 -#### 2.2 Record Manager(RM) +#### PageFile类(只能由BufferManager调用) +`RETCODE GetThisPage (PageNum pageNum, PagePtr &pageHandle) ;` +获取该文件中特定一页, 返回Page实例 -#### 2.3 Index Manager(IX) +`RETCODE AllocatePage (PagePtr &pageHandle);` +分配一个新的页, 返回Page实例 + +`RETCODE DisposePage (PageNum pageNum);` +释放(不再使用)特定的页 + +`RETCODE ForcePage (PageNum page, const PagePtr & pageHande);` +强制把一个页写入文件中的特定页中 + +#### BufferManager类(由其他类调用, 间接操作PageFile) + +`RETCODE GetPage (PageNum page, PagePtr & pBuffer); ` +获取一个特定的页, 返回Page实例 + +`RETCODE MarkDirty (PageNum page);` +把一个页标记为Dirty(修改过) + +`RETCODE LockPage (PageNum page);` +把一个页锁定在Buffer中 + +`RETCODE UnlockPage (PageNum page);` +把一个已锁定的页释放 + +`RETCODE ForcePage (PageNum page);` +强制把一个页写入文件 + +`RETCODE FlushPages ( );` +把Buffer中的所有页写入文件 + +`RETCODE AllocatePage (PagePtr & page); ` +分配一个新的页, 返回Page实例 + +`RETCODE DisposePage (PageNum page);` +释放特定的页 + +### 2.2 RM模块 + + +### 2.3 IX模块 -#### 2.4 System Manager(SM) + +### 2.4 SM模块 +#### SystemManager 类 + +`RETCODE CreateDb (const char * dbName, PageFileManagerPtr & pfMgr);` +创建一个新的数据库 + +`RETCODE OpenDb (const char *dbName); ` +打开一个数据库 + +`RETCODE CloseDb ( ); ` +关闭当前打开的数据库 + +`RETCODE CreateTable (const char *relName, Create relation, int attrCount, AttrInfo *attributes);` +(在当前打开的数据库中)创建表 + +`RETCODE DropTable (const char *relName);` +删除表 + +`RETCODE CreateIndex (const char *relName, const char *attrName);` +对某个表的一个属性建立索引 + +`RETCODE DropIndex (const char *relName, Destroy index, const char *attrName);` +删除索引 #### 2.5 Query Manager(QM) +`RETCODE Select ( +int nSelAttrs, // 查询的属性个数 +const RelAttr selAttrs[], // 查询的属性 +int nRelations, // 查询的关系表个数 +const char * const relations[], // 查询的关系表 +int nConditions, // 查询的条件个数 +const Condition conditions[]); // 查询的具体条件` +根据传入的参数执行查询操作 + +`RETCODE Insert (const char *relName, // relation to insert into +int nValues, // # values to insert +const Value values[]); // values to insert` + +`RETCODE Delete (const char *relName, // relation to delete from +int nConditions, // # conditions in Where clause +const Condition conditions[]); // conditions in Where clause` + + +`RETCODE Update (const char *relName, // relation to update +const RelAttr &updAttr, // attribute to update +const int bIsValue, // 0/1 if RHS of = is attribute/value +const RelAttr &rhsRelAttr, // attr on RHS of = +const Value &rhsValue, // value on RHS of = +int nConditions, // # conditions in Where clause +const Condition conditions[]); // conditions in Where clause` + ## 四. 使用语法 +#### Select + + +#### Insert + + +#### Update + + +#### Delete + ## 五. 实际测试