利用C++實現(xiàn)?然連接操作算法
1. 實驗目的
本次實驗三需要完成的內(nèi)容為實現(xiàn)然連接(natural join)操作算法,對兩個關(guān)系進然連接,具體實現(xiàn)基于塊的嵌套循環(huán)連接(Block-based Nested Loop Join)算法。
我們要實現(xiàn)的函數(shù)在 executer.cpp 文件中。
bool NestedLoopJoinOperator::execute(int numAvailableBufPages, File &resultFile)
2. 實驗內(nèi)容
首先,我們讀取兩個表頭的信息
TableId leftTableId = catalog->getTableId("r"); TableId rightTableId = catalog->getTableId("s"); badgerdb::File left = File::open(catalog->getTableFilename(leftTableId)); badgerdb::File right = File::open(catalog->getTableFilename(rightTableId));
運用兩層循環(huán)尋找兩個表中名稱與類型完全相同的屬性,將他們?nèi)繕擞洺鰜?,用于之后的自然連接操作。
vector<int> leftForeignKeyId; vector<int> rightForeignKeyId; for (int i = 0; i < leftTableSchema.getAttrCount(); i++) { for (int j = 0; j < rightTableSchema.getAttrCount(); j++) { if ((leftTableSchema.getAttrName(i) == rightTableSchema.getAttrName(j)) && (leftTableSchema.getAttrType(i) == rightTableSchema.getAttrType(j))) { leftForeignKeyId.push_back(i); rightForeignKeyId.push_back(j); break; } } }
準備操作做完后,開始進行自然連接操作。
用循環(huán)從磁盤中讀取兩個頁面的信息,記錄 io 操作次數(shù)
for (badgerdb::FileIterator leftPage = left.begin(); leftPage != left.end(); leftPage++) { badgerdb::Page *bufferedLeftPage; bufMgr->readPage(&left, (*leftPage).page_number(), bufferedLeftPage); numIOs += 1; for (badgerdb::FileIterator rightPage = right.begin(); rightPage != right.end(); rightPage++) { badgerdb::Page *bufferedRightPage; bufMgr->readPage(&right, (*rightPage).page_number(), bufferedRightPage); numIOs += 1;
之后,從表中讀取全部的元組的信息,進行對比。
讀取的元組信息有特殊的格式,并不能直接利用,所以需要先了解元組在表中儲存的格式,然后進行解讀。元組的存儲方式可以從 storage.cpp 中的 createTupleFromSQLStatement 函數(shù)中得知。
switch (dataType) { // (int) 56 (0011 1000) -> (char) '\0''\0''\0''8' case INT: { // convert int value into 4 byte representation case CHAR: { // (char(5) ) 'abc' -> 'abc00' case VARCHAR: { // (varchar(8) ) 'abc' -> '3''abc' (3 refer to the ascii // code number correspond alpha)
于是,我們根據(jù)注釋的存儲方式編寫解析函數(shù),該函數(shù)輸入為文件中存儲的元組,輸出為數(shù)組表示的直觀的元組內(nèi)容。
vector<string> analyze(string record, badgerdb::TableSchema schema)
先讀取其中一個表的元組,用塊來存儲。
for (badgerdb::PageIterator leftRecord = bufferedLeftPage->begin(); leftRecord != bufferedLeftPage->end(); leftRecord++) { vector<string> leftInfo = analyze(*leftRecord, leftTableSchema); numUsedBufPages += 1; block.push_back(leftInfo); if (block.size() < BLOCK_SIZE) { continue; }
然后讀取另一個表的元組信息,
for (badgerdb::PageIterator rightRecord = bufferedRightPage->begin(); rightRecord != bufferedRightPage->end(); rightRecord++) { numUsedBufPages += 1;
將兩個元組當中的屬性名相同的屬性列信息進行對比,
bool f = true; for(int i = 0; i < leftForeignKeyId.size(); i++) { if(leftInfo[leftForeignKeyId[i]] != rightInfo[rightForeignKeyId[i]]) { f = false; break; } }
如果全部相同,則代表需要進行自然連接操作。
if(f) { string current_line = "INSERT INTO TEMP_TABLE VALUES (" + leftInfo[0]; for (int i = 1; i < leftTableSchema.getAttrCount(); i++) { current_line = current_line + ", " + leftInfo[i]; } for (int i = 0; i < rightTableSchema.getAttrCount(); i++) { current_line = current_line + ", " + rightInfo[i]; } current_line = current_line + ");"; string tuple = HeapFileManager::createTupleFromSQLStatement(current_line, catalog); numResultTuples += 1; HeapFileManager::insertTuple(tuple, resultFile, bufMgr); }
否則不進行任何操作。
在全部循環(huán)都結(jié)束之后,塊中可能還會有剩余的信息沒有進行處理,此時再單獨對剩余信息進行處理,代碼基本相同。
3. 實驗結(jié)果
代碼運行結(jié)果如下:
到此這篇關(guān)于利用C++實現(xiàn)?然連接操作算法的文章就介紹到這了,更多相關(guān)C++連接操作算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
探討:將兩個鏈表非降序合并為一個鏈表并依然有序的實現(xiàn)方法
本篇文章是對將兩個鏈表非降序合并為一個鏈表并依然有序的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05Matlab實現(xiàn)繪制高階版本韋恩圖(upset圖)
韋恩圖隨著階數(shù)升高會越來越復雜,當階數(shù)達到7或者以上時幾乎沒辦法繪制,但是使用upset圖卻可以比較輕易的繪制。本文就來用Matlab實現(xiàn)繪制upset圖,需要的可以參考一下2023-01-01