这是 2020 年秋季学期《数据库系统概论》课程的大作业,用 Python 实现了数据库引擎与对应的 GUI。
工作量不算大,粗略计算有 8k 行 Python,其中 3.5k 是 antlr 生成,0.3 k 为 Qt 生成,还有不少空行与注释,实际工作量约为 3.5k 行。
本程序带有基于 PyQt5 开发的跨平台 GUI,但也允许在服务器等不便于用图形界面的地方安装使用纯 CLI 版本,因此有 requirements.txt
与 requirements_dev.txt
两个依赖文件,前者是核心依赖,后者递归调用前者并补充上了图形界面相关的库。在实现时我使用 ugly but work 的手法将 GUI 相关的 import 放到合适的地方以保证纯 CLI 版本的正常使用。
Python 需要 3.7 及以上的版本(或许我应该远见地预测一句低于 4.0?)
简单来说,使用 CLI 版本执行
pip install requirements.txt
安装完依赖后执行
python main.py
以启动程序,了解更多功能可以在上述指令加上 --help
以获取帮助。
使用 GUI 版本则执行
pip install requirements_dev.txt
安装完依赖后执行
python main.py --gui
以打开前端窗口。执行 SQL 请按 ctrl + enter,其他功能可自行摸索。
Pybase
文件夹中项目的核心部分PybaseGUI
文件夹中有单纯的前端部分report
文件夹中有我提价的项目报告,其中对系统设计进行了一定说明assignment
文件夹中有作业的相关文件,测试数据由于太大我放在 release 中了
助教提供了文法文件,我将它转化成了 antlr 所识别的文法文件(Pybase/SQL.g4)并进行了一定程度的扩充。antlr 配合 Visitor 模式是我在《编译原理》课程中学到的,短时间内若不再做框架调整则可默认后来人也能在完成本大作业前有相关基础。(没学过编原因此不知道如何解析也是我曾经退课的原因之一)
如果需要扩充新的语法,理应只需要简单修改文法文件即可。理论上 antlr 也可以支持大小写兼容的文法,且正是使用和本作业文法比较接近的 SQLite 举例,但可惜我看了示例的词法语法分离文件后不知道该如何使用,算是一个遗憾,将来的卷王选课同学可以尝试一下。
作业验收采用自行导入数据+运行固定 SQL 语句的方法,数据见 release,建立数据表的代码参加我写的测试SQL Pybase/tests/build.sql(注:助教没有提供能跑通的建表 SQL,需要自行完成),执行的固定 SQL 见 assignment/评分标准数据库-验收.xlsx (注:评分标准也在其中,但是里面的执行结果不见得是对的)
总的来说作业验收比较轻松,验收时段内可以任意次数尝试(现场debug)直到全部通过或自主放弃剩余项或时间截止。
我于 2019 年秋季学期选修本课,又在完成(翻译)页式文件系统与记录管理模块后退课(主要因为索引模块要用到 B 树而我当时没有精力和经验完成)。我在当时进行了粗略调研,没有找到使用 Python 完成本作业的学长,并且助教也表示“不反对使用 Python,但不保证它的文件 IO 水平足矣完成作业”,而我经过测试(当时写过一个测试记录文件assignment/C++与Python的IO性能测试.md)发现在相似的操作下 Python 的文件操作挺不错的,因此我就先将作业提供的页式文件系统翻译成 Python 然后开始按照作业引导完成。
2020 年秋季学期我再度选修课程,最终完成了助教所给测例中除了 ON UPDATE CASCADE 之外的所有测例,其结果足以说明使用 Python 确实可以简单高效地完成本作业。
本项目中已知 BUG 包括:
- B 树在大量删除下会出现 BUG 导致索引异常
- 没有实现外键反向完整性,即若表 A 的列 b 是指向表 B 的列 b 的外键,那么 B.b 更新时不会考虑 A.b 的完整性
可以实现的 feature 有:
- 支持 order by 语法,很利于在没有 GUI 的情况下观测查询结果(图形界面可以对结果直接做多关键字排序)
- 将 limit 与 offset 加到扫描过程中而非出结果后再暴力截断
- 为前端添加分页功能
- 索引查询时使用(估算意义下)最优的单索引而不是分别用多个索引取交集
此前听见有同学吐槽 Github 上的学长代码没有一个能跑通的,我想由于 Python 本身的跨平台性与一定范围内的兼容性,后来者理应可以相对容易地跑通我的代码。截止 min{Python4 上线,我离开 UHT,编原或数据库大作业重大课改},跑通本仓库遇到的人可以通过我 github 公开邮箱或本仓库 issue 区寻求帮助(建议过于低级、个性化的选择前者,遇到依赖库后向兼容性等问题选择后者),这种情况下请说明清楚操作系统、python 版本、依赖库版本、执行的操作、期望的输出、完整错误输出。
注:对于本仓库中的 BUG,我会收到反馈后罗列在 README 中,但我既不会修复 BUG 也不会接受任何 PR,因为如果你希望使用一个数据库系统,那么请选择专业的数据库而不是 toy 级大作业;如果你希望完成一份大作业,那么你至少应该具备修复 bug 与增加功能的能力。