数据库系统学习记录

原标题 UC Berkeley cs61A/cs186学习记录

因为学过c语言也用这个写过大作业,猜想cs61A对我来说难度应该不会特别那啥。。并且下学期即将面对计院知名的很顶的课《数据库系统》和大作业MiniSQL,所以寒假需要预习一下,希望不要半途而废。。如果两个应付不过来后面再看着调整吧。。

网课在Youtube和b站上都有,课程作业和资料在EECS Instructional Support Group Home Page (berkeley.edu)可以下载到。另外这里是因为我个人需求选择了这两门课,其他国外大学的网课可以参考cs自学指南自行进行选择,也可以根据mit的cs培养方案选择。

//2022.2.21更新

我鸽了,我忏悔,之前花了两天配作业环境还装了双系统死活运行不起来。。。下学期一定好好学习。。。后面要开始上正经的数据库系统了,用的教材是Database System Concepts by Abraham Silberschatz,跟上学期汇编一样在这里记录进度

———————————————————2022.4.15更新—————————————————————

完成春学期大程之后前来更新。。前几次作业基本上是简单的sql语言运用,下载Mysql之后在命令行中运行,这里就直接把我的前几次实验报告放在这里。分别是Lab1 DBMS的安装和使用,Lab2 SQL数据定义和操作,Lab3 SQL数据完整性,Lab4 SQL 安全性

需要注意的是,在前四次作业中我使用的都是64位的Mysql,但是Lab5中因为我使用的是32位的QT Creator与数据库进行连接,所以重新下载了32位的Mysql,后文中会有安装说明,看需求选择相应的版本。

Lab5作业要求如下:

//闲聊部分

Lab5看起来很复杂,但实际上内核是很简单的,掌握了基本语法之后,写完一个函数其余函数就可以复制粘贴,修改一下逻辑即可。我们助教原话“春学期大程不水 什么时候水”可能比较口语化hhh,但是确实说明这个难度很低。作业原先是在4.15 00:00截止,我从4.12晚上开始做,通了一晚上+一早上干完程序写完实验报告准备美美上传的时候,突然发现作业延期截止了,顿时感觉我就是个被演爆了的小丑。。。有这时间睡觉不香吗。。不过至少至此春学期的任务就告一段落了,后面即将开始MiniSQL的编写。春学期基本上聚焦在数据库的使用上,到夏学期就是重点在数据库的内核上了。

//正式部分

我所使用的是QT Creator5.9.0作为开发平台,连接读取Mysql中储存的数据。即使下载了x64的QT,其中自带的gcc编译器MinGW只有32位的版本,因此必须安装32位的Mysql才能保证位数对应。但是官网上的Mysql虽然标了x86版本(32位),但是在后续安装组件的过程中,只有x64版本可选,因此位数还是不对应的。所以另外找到了32位Mysql的安装包自行编译文件才安装成功。下图中若没有ODBC和图形界面的需求,可以只下载MySQL Server这个组件,我个人比较倾向于使用命令行而不是图形界面运行Mysql。

Mysql安装组件的选择

QT的下载是在https://download.qt.io/archive/qt/,选择5.9.0版本,下载qt-opensource-windows-x86-5.9.0.exe这一文件即可。运行之后,会有设置组件的步骤,这一步中点开qt5.9.0,里面可以看到MinGW32这个组件,安装即可,其余如MSVC类的组件用于连接vscode,依据需求进行下载。在5.12.0版本中似乎可以直接下载到MinGW64,则可以不必重新下载32位的Mysql,直接根据我在Lab1中的步骤进行即可。

下载完成之后,配置系统环境变量,在设置中搜索path,在搜索弹出的链接中选择系统环境变量,点击环境变量,在系统变量中找到path双击,进入编辑页面,新建变量后把安装好的QT的bin文件路径复制到其中,则QT安装全部完成

配置环境变量
配置环境变量

下面安装32位Mysql

将mysql-5.6.39-win32.zip解压到指定目录中,修改my-default.ini的内容如下,并保存

ini文件

修改之后增加环境变量。和QT相同步骤把Mysql的bin文件路径添加到path中。之后,在C盘中找到cmd.exe,并以【管理员权限】打开。分别执行以下指令:

   E: (Mysql装在哪个盘就哪个盘加冒号)

   cd  mysql-5.6\bin (即在【cd 】之后输入mysql的bin文件的所在位置)

  mysqld -initalize -user=mysql -console

  mysqld -install,输入该指令后会打印 Service successfully installed

  net start mysql,输入该指令后会打印MySQL服务已经启动成功。至此MYSQL5.6已经安装成功,并且已运行。

后面进行Mysql的用户密码设置 windows+R,输入cmd之后回车,打开cmd.exe,在命令行中输入【mysql -u root -p】回车后会出现 【Enter password: 】 ,第一次登陆直接回车,进入mysql软件。在mysql>后输入 【set password for [email protected]=password(‘123456’);】,则用户root的密码被设置为123456。输入【exit】可以退出数据库

之后重新登陆,在Enter password: 之后输入密码就可以登录进入数据库。随后的操作根据我的Lab1的测试步骤可以对数据库进行操作。

———————————————————2022.9.29更新—————————————————————

没想到拖了这么久。。因为期中之后minisql实在是非常痛苦,并且考试周之后两门复杂的短学期也非常忙,直到七月底才正式放暑假,就一直搁置了。暑假虽然空了些,但没想到居然沉迷游戏了根本没学习XD。。现在痛定思痛了也正好比较空,就赶紧把这里补上。

将32位Mysql和QT creater配置完毕之后,新建project,并且在main或者mainwindow文件中输入如下代码进行测试查看连接是否成功。(我在写lab5的时候主要代码均在mainwindow.cpp中,main.cpp内只有创建proj时默认生成的代码)这里包含所有甚至多余的我所使用到的库。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QDebug>
#include <QApplication>
#include <QMessageBox>
#include <QtSql>
#include <QFile>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect_mysql();
}

MainWindow::~MainWindow()
{
    delete ui;
}


//连接数据库
void MainWindow::connect_mysql()
{
    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("127.0.0.1");      //连接数据库主机名,这里需要注意(若填的为”127.0.0.1“,出现不能连接,则改为localhost)
        db.setPort(3306);                 //连接数据库端口号
        db.setDatabaseName("library");      //连接数据库名
        db.setUserName("root");          //你使用的mysql中的数据库用户名
        db.setPassword("12345678");    //你使用的mysql中的数据库密码
        db.open();
        if(!db.open())
        {
            qDebug()<<"不能连接"<<"connect to mysql error"<<db.lastError().text();
         //使用命令行输出报错信息
            return ;
        }
        else
        {
             qDebug()<<"连接成功"<<"connect to mysql OK";
        }
}

连接成功后即可开始编写代码。qt可以很方便的绘制ui,即选中项目中Forms文件夹,有一个mainwindow.ui文件,双击后即可打开设计界面,可以拖动组件进行编辑,使用方法类似于VB,即利用组件名称来调用其中的内容(eg.文本框中的输入,按钮的状态),在mainwindow.cpp中利用函数表示对应状态的触发(如按钮被按下即执行该函数中的代码)虽然这里使用的是C++,但是编写过程中基本没有C++特有的一些写法,只有C语言基础也可以很快写完。

我所绘制的界面,在右上方的框内可以改变其属性

这里选中了文本框addbno,配合其他文本框和addbookButton按钮可以实现往数据库中添加书籍信息。后文以该函数为例。函数功能:当图书馆中已经存在要添加的书号时,在原有库存数量上增加对应数量;若不存在,则将书籍信息添加到数据库中。先在头文件mainwindow.h中声明函数。

void on_addbookButton_clicked();

在mainwindow.cpp中编辑函数如下,对应命令的作用以注释形式添加在代码内

void MainWindow::on_addbookButton_clicked()
{
     QSqlQuery query;
     QString bno       = ui->addbno->text();
     QString category  = ui->addcategory->text();
     QString title     = ui->addtitle->text();
     QString press     = ui->addpress->text();
     QString year      = ui->addyear->text();
     QString author    = ui->addauthor->text();
     const double price= ui->addprice->text().toDouble();
     const int total   = ui->addtotal->text().toInt();
     const int stock   = ui->addstock->text().toInt();

//读取对应文本框中输入的信息,并储存在对应字符串中
//text().toInt()类似强制类型转换,若不如此在一些操作中会出错


     if(bno==NULL or category==NULL or title==NULL or press==NULL or year==NULL or author==NULL or price==NULL or total==NULL or stock==NULL
             or total<0 or stock<0 or price<0)
     {
         QMessageBox::information(this,"警告","请完整输入合法内容!");
     }


//合法性判断

     else{
         QString str=QString("select *from book where bno = '%1'").arg(bno);

//利用sql语句在数据库中查询,先将变量bno的内容添加到sql语句中并保存到字符串str
         QSqlQuery query;
         query.exec(str);
//执行sql语句,返回的表格信息会储存在query中
         if(query.first())
         {
             QString cmd = QString("update book set price='%1',total=total+'%2',stock=stock+'%3' where bno = '%4'")
                     .arg(price).arg(total).arg(stock).arg(bno);
             query.exec(cmd);

             qDebug()<<"添加成功";

//命令行返回执行结果
         }
         else {
             QString cmd = QString("insert into book values('%1','%2','%3','%4','%5','%6','%7','%8','%9');")
                     .arg(bno).arg(category).arg(title).arg(press).arg(year).arg(author).arg(price).arg(total).arg(stock);
             if(!query.exec(cmd))
             {
                 qDebug() << "Error to Insert Into Database " << myDatabase.lastError();

                 return;
             }
             else qDebug()<<"添加成功";
        }
     }
         ui->addbno->clear();
         ui->addcategory->clear();
         ui->addtitle->clear();
         ui->addpress->clear();
         ui->addyear->clear();
         ui->addauthor->clear();
         ui->addprice->clear();
         ui->addtotal->clear();
         ui->addstock->clear();

//清空对应文本框
}

头文件内容

在熟悉这里的写法之后其实后续的大多数功能都非常简单了,利用TableView组件和下列代码可以轻松的做到数据可视化。

void MainWindow::on_viewbook_clicked()
{
        QSqlQuery query;
        QString str1=QString("select * from book");
        query.exec(str1);
        QSqlQueryModel *model=new QSqlQueryModel;

        model->setQuery(str1);

        ui->resultView->setModel(model);
        ui->resultView->show();
        qDebug()<<"查找完成";
}

唯一有点问题的是bulkadding即批量导入,可以在规定输入格式后使用正则表达式或者line.split(“,”)【其中引号内是你所规定的分隔符】,即可将输入的信息以list的格式保存起来。我将bulkadding的内容保存在一个txt文件中,用file.open打开、QTextStream读取信息之后,再利用split分割成表格信息,分别进行读取。参考代码如下

    bool exist = QFile::exists("E:/qtcode/test06/add.txt");
    if (!exist) {QMessageBox::information(this,"警告","文件不存在");}
    else{
        QFile file("E:/qtcode/test06/add.txt");
        file.open(QIODevice::ReadOnly);
        QTextStream in(&file);
        while(!in.atEnd())
        {
            QString line = in.readLine();
            line.remove("\r\n");
            QStringList list=line.split(",");

            QString bno       = list.at(0);
            QString category  = list.at(1);
            QString title     = list.at(2);
            QString press     = list.at(3);
            QString year      = list.at(4);
            QString author    = list.at(5);
            QString price     = list.at(6);
            QString total     = list.at(7);
            QString stock     = list.at(8);
            QString str=QString("select *from book where bno = '%1'").arg(bno);
            QSqlQuery query;
            query.exec(str);
}

将信息分别存入对应变量后,后续操作与其他函数基本一致。最后运行即可得到对应的exe文件。这里可以看看我当时的实验报告(助教甚至没有要求上传源代码,验收也并不是必须进行的步骤而是一个加分项…所以说真的很水)并且我当时是有一个bug无法解决的,即当某书被全部借出后,若还有同学希望借这本书需要返回最近预定归还的时间,这个涉及到归还日期的比较,又要考虑日期是否合法有点复杂,我就伪造了一个氵过去了。。

【关于minisql的碎碎念】数据库系统的重头就是minisql。因为有一位前辈([email protected]小角龙 )对于计院本科生的课程设计提出了许多意见,并且参与了计算机学院课改的座谈会,我们这一届使用了最新的实验框架。事实上座谈会在21年底才进行,针对于数据库系统这门课的改进可以说是非常匆忙的,我非常幸运的选上了主持这次改进的老师(并且他无论从学术水平、教育热情、教学水平、lab质量上都可以是无可指摘的优秀,课程水平绝对算是计院第一等的老师了),整体框架的代码魔改自cmu15-445,是我们班的助教gg今年刚研一的大佬纯手撸出来的,和原版框架主要在BusTube上区别较大,各处也有不小的改写,因此是没法抄袭github上现有的项目代码的。我们组基本上也是纯肝出来的orz。因为是第一年时间不够(如果我没记错的话lab5验收那天助教gg还在改框架)因此事务transaction相关部分都没有要求(下一届就会有这方面要求了,因此就这来说要求是变高的,不过他们的指导文档之类的也会更加完善,我们这届甚至还要帮助教gg找bug写test),同时test部分也都只有比较基础的部分,没办法涵盖各种情况,很多test需要自己去写。甚至有可能test全过但是最终合起来前面突然冒出来一大堆bug。。当时改得确实非常痛苦。。不过有一说一这大概真的是一个非常锻炼人水平的项目,包括前端和后端和各部分之间的接口设计和我们以前写过的零碎的lab完全不是一个规模的,整体设计也非常有意思,如果有时间的话我推荐所有人都可以试一试写一下这个折磨人的玩意()

由于我是外专业没什么认识的人,因此在分小组的时候我是摆烂让助教gg随机分配的,最后分到了一个19级大佬和一个感觉是水平有限被迫咸鱼的图灵班老哥,图灵老哥熬了两个晚上写了大半的index还是有几个测试过不了就开始摆烂了,完全没有参与最后的debug模块,我属于中规中矩的改完了我负责的部分,其余所有部分包括一个针对buffer_pool优化的bonus和图灵老哥的烂摊子全部是19级老哥改完的,真的感恩orz

本项目是利用WSL在linux环境下编译,语言是C++,我所使用的软件是clion,debug/test都蛮方便的,个人感觉比vscode是更舒服一些的。助教在实验指导文档中有非常详尽的环境配置教程,跟着做就可以。我主要负责的是executor部分所以没有办法涉及很细致的index

实验指导文档

留下评论

您的电子邮箱地址不会被公开。 必填项已用*标注