利用C++實現(xiàn)?然連接操作算法
1. 實驗目的
本次實驗三需要完成的內容為實現(xiàn)然連接(natural join)操作算法,對兩個關系進然連接,具體實現(xiàn)基于塊的嵌套循環(huán)連接(Block-based Nested Loop Join)算法。
我們要實現(xiàn)的函數(shù)在 executer.cpp 文件中。
bool NestedLoopJoinOperator::execute(int numAvailableBufPages,
File &resultFile)2. 實驗內容
首先,我們讀取兩個表頭的信息
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)尋找兩個表中名稱與類型完全相同的屬性,將他們全部標記出來,用于之后的自然連接操作。
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ù)組表示的直觀的元組內容。
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)都結束之后,塊中可能還會有剩余的信息沒有進行處理,此時再單獨對剩余信息進行處理,代碼基本相同。
3. 實驗結果
代碼運行結果如下:

到此這篇關于利用C++實現(xiàn)?然連接操作算法的文章就介紹到這了,更多相關C++連接操作算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
探討:將兩個鏈表非降序合并為一個鏈表并依然有序的實現(xiàn)方法
本篇文章是對將兩個鏈表非降序合并為一個鏈表并依然有序的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05
Matlab實現(xiàn)繪制高階版本韋恩圖(upset圖)
韋恩圖隨著階數(shù)升高會越來越復雜,當階數(shù)達到7或者以上時幾乎沒辦法繪制,但是使用upset圖卻可以比較輕易的繪制。本文就來用Matlab實現(xiàn)繪制upset圖,需要的可以參考一下2023-01-01

