C++数据库系统原理实验——选择,投影、连接的模拟

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sstream>
#include <limits>

using namespace std;

// 关系类
class Relation {
public:
    string name;                // 关系名称
    vector<string> attributes;  // 属性列表
    vector<vector<string>> tuples;  // 元组列表

    // 构造函数
    Relation(string name, vector<string> attributes, vector<vector<string>> tuples) {
        this->name = name;
        this->attributes = attributes;
        this->tuples = tuples;
    }
};

vector<Relation> objects;

// 手动创建一个关系的函数
Relation createRelationManually() {
    int numAttributes, numTuples;
    string relationName;
    vector<string> attributes;
    vector<vector<string>> tuples;

    // 输入关系名称
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "请输入关系名称: ";
    getline(cin, relationName);

    // 输入属性
    cout << "请输入属性数量: ";
    cin >> numAttributes;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入后的换行符
    cout << "请输入属性列表(用空格分隔): ";
    for (int i = 0; i < numAttributes; ++i) {
        string attribute;
        cin >> attribute;
        attributes.push_back(attribute);
    }
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入后的换行符

    // 输入元组
    cout << "请输入元组数量: ";
    cin >> numTuples;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入后的换行符
    cout << "请输入元组(每个值之间用空格分隔,每个元组占一行):" << endl;
    for (int i = 0; i < numTuples; ++i) {
        vector<string> tuple;
        string tupleLine;
        getline(cin, tupleLine);
        istringstream ss(tupleLine);
        string value;
        while (ss >> value) {
            tuple.push_back(value);
        }
        tuples.push_back(tuple);
    }

    // 创建并返回关系
    return Relation(relationName, attributes, tuples);
}
// 获取关系的所有属性
vector<string> getAllAttributes(const Relation& relation) {
    return relation.attributes;
}
// 单关系的投影操作
Relation project(const Relation& relation, const vector<string>& attributeList) {
    vector<vector<string>> newTuples;

    // 获取需要的属性在原关系中的索引
    unordered_map<string, int> attributeIndexMap;
    for (int i = 0; i < relation.attributes.size(); i++) {
        attributeIndexMap[relation.attributes[i]] = i;//将键和值联系起来
    }

    // 对每个元组进行投影操作
    for (const vector<string>& tuple : relation.tuples) {
        vector<string> newTuple;
        for (const string& attribute : attributeList) {
            if (attributeIndexMap.count(attribute)) {//判断属性是否在关系中
                newTuple.push_back(tuple[attributeIndexMap[attribute]]);
            }
        }
        newTuples.push_back(newTuple);
    }

    return Relation(relation.name, attributeList, newTuples);
}

// 单关系的选择操作
Relation select(const Relation& relation, const string& condition) {
    vector<vector<string>> newTuples;

    // 解析条件表达式
    string attributeName = condition.substr(0, condition.find(' '));//属性
    string operatorType = condition.substr(condition.find(' ') + 1, 1);//运算符
    string constantValue = condition.substr(condition.find(operatorType) + 2);//常量值


    // 对每个元组进行选择操作——找where条件中属性下标
    for (const vector<string>& tuple : relation.tuples) {
        int attributeIndex = -1;
        for (int i = 0; i < relation.attributes.size(); i++) {
            if (relation.attributes[i] == attributeName) {
                attributeIndex = i;
                break;
            }
        }
        // 根据操作符类型进行判断
        if (operatorType == "=" && tuple[attributeIndex] == constantValue) {
            newTuples.push_back(tuple);
        }
        else if (operatorType == "<" && tuple[attributeIndex] < constantValue) {
            newTuples.push_back(tuple);
        }
        else if (operatorType == ">" && tuple[attributeIndex] > constantValue) {
            newTuples.push_back(tuple);
        }
    }
    return Relation(relation.name, relation.attributes, newTuples);
}

// 关系连接操作
Relation join(const Relation& relation1, const Relation& relation2, const string& condition) {
    vector<vector<string>> newTuples;

    // 解析连接条件
    string attributeName1 = condition.substr(0, condition.find('=') - 1);
    string attributeName2 = condition.substr(condition.find('=') + 2);

    // 获取连接属性在两个关系中的索引
    int attributeIndex1 = -1;
    int attributeIndex2 = -1;
    for (int i = 0; i < relation1.attributes.size(); i++) {
        if (relation1.attributes[i] == attributeName1) {
            attributeIndex1 = i;
            break;
        }
    }
    for (int i = 0; i < relation2.attributes.size(); i++) {
        if (relation2.attributes[i] == attributeName2) {
            attributeIndex2 = i;
            break;
        }
    }

    // 对每个元组进行连接操作
    for (const vector<string>& tuple1 : relation1.tuples) {
        for (const vector<string>& tuple2 : relation2.tuples) {
            if (tuple1[attributeIndex1] == tuple2[attributeIndex2]) {
                vector<string> newTuple = tuple1;
                newTuple.insert(newTuple.end(), tuple2.begin(), tuple2.end());
                newTuples.push_back(newTuple);
            }
        }
    }
    // 合并属性列表
    vector<string> newAttributes = relation1.attributes;
    newAttributes.insert(newAttributes.end(), relation2.attributes.begin(), relation2.attributes.end());
    return Relation("Join", newAttributes, newTuples);
}

// 根据关系名获取关系对象
Relation getRelation(const string& relationName) {
    // 根据关系名称返回对应的关系对象
    // 这里假设已经定义了一些关系对象,并根据名称进行查找和返回
    // 如果关系对象不存在,可以返回一个空的关系对象
    for (const Relation newRelation : objects) {
        if (newRelation.name == relationName) {
            return newRelation;
        }
    }
    return Relation("", {}, {});
}
// 解析属性列表
vector<string> getAttributeList(const string& attributeList) {
    vector<string> attributes;
    string attribute;
    istringstream attributeStream(attributeList);

    // 将属性列表分解为单个属性
    while (getline(attributeStream, attribute, ',')) {
        attributes.push_back(attribute);
    }
    return attributes;
}
//无连接,单条件
string getTokens5(vector<string>tokens) {
    if (tokens.size() > 6) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 5; i < tokens.size(); i++) {
            newToken += tokens[i];
            if (i != tokens.size() - 1) {
                newToken += ' ';
            }
        }
        tokens[5] = newToken;
    }
    return tokens[5];
}
//有连接,单条件
string getTokens7(vector<string>tokens) {
    if (tokens.size() > 8) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 7; i < tokens.size(); i++) {
            newToken += tokens[i];
            if (i != tokens.size() - 1) {
                newToken += ' ';
            }
        }
        tokens[7] = newToken;
    }
    return tokens[7];
}
// 解析查询语句,执行查询操作
string getTokens5_7(vector<string>tokens) {
    if (tokens.size() > 6) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 5; i < 8; i++) {
            newToken += tokens[i];
            if (i != 7) {
                newToken += ' ';
            }
        }
        tokens[5] = newToken;
    }
    return tokens[5];
}
string getTokens7_9(vector<string>tokens) {
    if (tokens.size() >= 7) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 7; i < 10; i++) {
            newToken += tokens[i];
            if (i != 9) {
                newToken += ' ';
            }
        }
        tokens[7] = newToken;
    }
    return tokens[7];
}
string getTokens9_11(vector<string>tokens) {
    if (tokens.size() > 10) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 9; i < 12; i++) {
            newToken += tokens[i];
            if (i != 11) {
                newToken += ' ';
            }
        }
        tokens[9] = newToken;
    }
    return tokens[9];
}
string getTokens11_13(vector<string>tokens) {
    if (tokens.size() > 12) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 11; i < 14; i++) {
            newToken += tokens[i];
            if (i != 13) {
                newToken += ' ';
            }
        }
        tokens[11] = newToken;
    }
    return tokens[11];
}
string getTokens12_14(vector<string>tokens) {
    if (tokens.size() > 13) {
        // 将第6个及以后的所有的字符串组成一个新的字符串
        string newToken;
        for (int i = 12; i < 15; i++) {
            newToken += tokens[i];
            if (i != 14) {
                newToken += ' ';
            }
        }
        tokens[12] = newToken;
    }
    return tokens[12];
}
Relation executeQuery(const string& query) {
    vector<string> tokens;//将空格分割出来的单词保存
    string token;
    istringstream tokenStream(query);
    // 将查询语句分解为单词
    while (getline(tokenStream, token, ' ')) {
        tokens.push_back(token);
    }
    // 执行查询操作
    if (tokens[0] == "SELECT" && tokens[1] == "*") {
        if (tokens[2] == "FROM") {
            // 单关系的投影操作
            if (tokens.size() == 4) {
                return project(getRelation(tokens[3]), getAllAttributes(getRelation(tokens[3])));
            }
            // 单关系的选择操作
            else if (tokens.size() == 8 && tokens[4] == "WHERE") {
                return select(getRelation(tokens[3]), getTokens5(tokens));
            }
            else if (tokens[4] == "JOIN" && tokens[6] == "WHERE") {
                if (tokens.size() == 10) {
                    return join(getRelation(tokens[3]), getRelation(tokens[5]), getTokens7(tokens));
                }
                else if (tokens[10] == "AND" && tokens.size() == 14) {
                    return select(join(getRelation(tokens[3]), getRelation(tokens[5]), getTokens7_9(tokens)), getTokens11_13(tokens));
                }
            }
            else if (tokens[8] == "AND" && tokens.size() == 12) {
                return select(select(getRelation(tokens[3]), getTokens5_7(tokens)), getTokens9_11(tokens));
            }
            else {
                return Relation("", {}, {});
            }
        }
        // "SELECT A,B FROM Relation1 WHERE A = 1",
        // "SELECT A,B FROM Relation1",
    }// "SELECT A,B FROM Relation1 JOIN Relation2 WHERE C = C",
    //      0   1    2      3       4       5       6   7 8 9
    else if (tokens[0] == "SELECT") {
        if (tokens[2] == "FROM" && tokens.size() == 4) {
            return project(getRelation(tokens[3]), getAttributeList(tokens[1]));
        }
        // 单关系多属性单条件的选择和投影操作
        else if (tokens[2] == "FROM" && tokens[4] == "WHERE") {
            return project(select(getRelation(tokens[3]), getTokens5(tokens)), getAttributeList(tokens[1]));
        }
        else if (tokens[2] == "FROM" && tokens[4] == "JOIN" && tokens[6] == "WHERE") {
            return join(getRelation(tokens[3]), getRelation(tokens[5]), getTokens7(tokens));
        }
        else
            return Relation("", {}, {});
    }
    else
        return Relation("", {}, {});
}
vector<string> testQueries() {
    // 查询语句
    vector<string> queries = {
        "SELECT * FROM Relation1",//
        "SELECT * FROM Relation1 WHERE sno = 0118",//
        "SELECT * FROM Relation1 JOIN Relation2 WHERE sno = sno",//
        "SELECT * FROM Relation1 WHERE sno = 0118 AND age > 22",//
        "SELECT * FROM Relation1 JOIN Relation2 WHERE sno = sno AND grade > 95",//
        "SELECT sno,name,sex FROM Relation1 JOIN Relation2 WHERE sno = sno",//
        "SELECT sno,sex FROM Relation2",//
        "SELECT age,name FROM Relation1 WHERE age = 22",//
    };
    return queries;
}
int main() {
    // 示例:手动创建一个关系
    int n;
    cout << "你要创建几个表格:"<<endl;
    cin >> n;
    for (int i = 0; i < n; i++) {
        Relation it = createRelationManually();
        objects.push_back(it);
    }
    // 打印新创建的关系以验证输入
   /* for (const Relation newRelation : objects) {
        cout << "新创建的关系: " << newRelation.name << endl;
        cout << "属性: ";
        for (const auto& attr : newRelation.attributes) {
            cout << attr << " ";
        }
        cout << "\n元组:" << endl;
        for (const auto& tuple : newRelation.tuples) {
            for (const auto& value : tuple) {
                cout << value << " ";
            }
            cout << endl;
        }
    }*/

    vector<string> queries = testQueries();
    for (const string& query : queries)
    {
        cout << "Query: " << query << endl;
        Relation result = executeQuery(query);
        cout << "\t\t" << result.name << endl;
        cout << "|-----------------------------------------------------------------------------------------------|" << endl;
        for (const string& attribute : result.attributes)
        {
            cout << "|\t" << attribute << "\t";
        }
        cout << "|" << endl;
        cout << "|-----------------------------------------------------------------------------------------------|" << endl;
        for (const vector<string>& tuple : result.tuples)
        {
            for (const string& value : tuple)
            {
                cout << "|\t" << value << "\t";
            }
            cout << "|" << endl;
            cout << "|-----------------------------------------------------------------------------------------------|" << endl;
        }
        cout << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

try again!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值