├── .gitignore ├── README.md ├── lab1 ├── .gitignore ├── README.md ├── gui │ ├── gui.py │ └── transaction.py ├── main.py └── src │ ├── ER图.jpg │ ├── Pycharm生成的系统图.png │ ├── system.png │ ├── teaching_management_system_class.sql │ ├── teaching_management_system_college.sql │ ├── teaching_management_system_course.sql │ ├── teaching_management_system_department.sql │ ├── teaching_management_system_dorm.sql │ ├── teaching_management_system_laboratory.sql │ ├── teaching_management_system_sc.sql │ ├── teaching_management_system_student.sql │ ├── teaching_management_system_teacher.sql │ ├── 主界面运行截图.png │ ├── 事务管理主要流程图.jpg │ ├── 事务管理界面.png │ ├── 删除学生信息主要流程图.jpg │ ├── 查询优化GUI展示.png │ ├── 磁盘操作截图.png │ └── 视图创建界面.png └── lab2 ├── .gitignore ├── README.md ├── disk ├── join │ ├── hash │ │ ├── hash │ │ │ ├── r0_0.blk │ │ │ ├── r0_1.blk │ │ │ ├── r1_0.blk │ │ │ ├── r1_1.blk │ │ │ ├── r2_0.blk │ │ │ ├── r2_1.blk │ │ │ ├── r3_0.blk │ │ │ ├── r3_1.blk │ │ │ ├── r3_2.blk │ │ │ ├── r4_0.blk │ │ │ ├── r4_1.blk │ │ │ ├── r4_2.blk │ │ │ ├── r4_3.blk │ │ │ ├── r5_0.blk │ │ │ ├── r5_1.blk │ │ │ ├── r5_2.blk │ │ │ ├── r5_3.blk │ │ │ ├── r6_0.blk │ │ │ ├── r6_1.blk │ │ │ ├── s0_0.blk │ │ │ ├── s0_1.blk │ │ │ ├── s0_2.blk │ │ │ ├── s0_3.blk │ │ │ ├── s1_0.blk │ │ │ ├── s1_1.blk │ │ │ ├── s1_2.blk │ │ │ ├── s1_3.blk │ │ │ ├── s1_4.blk │ │ │ ├── s2_0.blk │ │ │ ├── s2_1.blk │ │ │ ├── s2_2.blk │ │ │ ├── s2_3.blk │ │ │ ├── s2_4.blk │ │ │ ├── s3_0.blk │ │ │ ├── s3_1.blk │ │ │ ├── s3_2.blk │ │ │ ├── s3_3.blk │ │ │ ├── s3_4.blk │ │ │ ├── s4_0.blk │ │ │ ├── s4_1.blk │ │ │ ├── s4_2.blk │ │ │ ├── s4_3.blk │ │ │ ├── s4_4.blk │ │ │ ├── s5_0.blk │ │ │ ├── s5_1.blk │ │ │ ├── s5_2.blk │ │ │ ├── s5_3.blk │ │ │ ├── s5_4.blk │ │ │ ├── s6_0.blk │ │ │ ├── s6_1.blk │ │ │ ├── s6_2.blk │ │ │ ├── s6_3.blk │ │ │ └── s6_4.blk │ │ └── res │ │ │ ├── rs0.blk │ │ │ ├── rs1.blk │ │ │ ├── rs10.blk │ │ │ ├── rs11.blk │ │ │ ├── rs12.blk │ │ │ ├── rs13.blk │ │ │ ├── rs14.blk │ │ │ ├── rs15.blk │ │ │ ├── rs16.blk │ │ │ ├── rs17.blk │ │ │ ├── rs18.blk │ │ │ ├── rs19.blk │ │ │ ├── rs2.blk │ │ │ ├── rs20.blk │ │ │ ├── rs21.blk │ │ │ ├── rs22.blk │ │ │ ├── rs23.blk │ │ │ ├── rs24.blk │ │ │ ├── rs25.blk │ │ │ ├── rs26.blk │ │ │ ├── rs27.blk │ │ │ ├── rs28.blk │ │ │ ├── rs29.blk │ │ │ ├── rs3.blk │ │ │ ├── rs30.blk │ │ │ ├── rs31.blk │ │ │ ├── rs32.blk │ │ │ ├── rs33.blk │ │ │ ├── rs34.blk │ │ │ ├── rs35.blk │ │ │ ├── rs36.blk │ │ │ ├── rs37.blk │ │ │ ├── rs38.blk │ │ │ ├── rs39.blk │ │ │ ├── rs4.blk │ │ │ ├── rs40.blk │ │ │ ├── rs41.blk │ │ │ ├── rs42.blk │ │ │ ├── rs43.blk │ │ │ ├── rs44.blk │ │ │ ├── rs45.blk │ │ │ ├── rs46.blk │ │ │ ├── rs47.blk │ │ │ ├── rs48.blk │ │ │ ├── rs49.blk │ │ │ ├── rs5.blk │ │ │ ├── rs50.blk │ │ │ ├── rs51.blk │ │ │ ├── rs52.blk │ │ │ ├── rs53.blk │ │ │ ├── rs54.blk │ │ │ ├── rs55.blk │ │ │ ├── rs56.blk │ │ │ ├── rs57.blk │ │ │ ├── rs58.blk │ │ │ ├── rs59.blk │ │ │ ├── rs6.blk │ │ │ ├── rs60.blk │ │ │ ├── rs61.blk │ │ │ ├── rs62.blk │ │ │ ├── rs63.blk │ │ │ ├── rs64.blk │ │ │ ├── rs65.blk │ │ │ ├── rs66.blk │ │ │ ├── rs67.blk │ │ │ ├── rs68.blk │ │ │ ├── rs69.blk │ │ │ ├── rs7.blk │ │ │ ├── rs70.blk │ │ │ ├── rs71.blk │ │ │ ├── rs72.blk │ │ │ ├── rs73.blk │ │ │ ├── rs74.blk │ │ │ ├── rs75.blk │ │ │ ├── rs76.blk │ │ │ ├── rs77.blk │ │ │ ├── rs78.blk │ │ │ ├── rs79.blk │ │ │ ├── rs8.blk │ │ │ ├── rs80.blk │ │ │ ├── rs81.blk │ │ │ ├── rs82.blk │ │ │ ├── rs83.blk │ │ │ ├── rs84.blk │ │ │ ├── rs85.blk │ │ │ ├── rs86.blk │ │ │ ├── rs87.blk │ │ │ ├── rs88.blk │ │ │ ├── rs89.blk │ │ │ ├── rs9.blk │ │ │ ├── rs90.blk │ │ │ ├── rs91.blk │ │ │ ├── rs92.blk │ │ │ ├── rs93.blk │ │ │ ├── rs94.blk │ │ │ ├── rs95.blk │ │ │ └── rs96.blk │ ├── nlj │ │ ├── rs0.blk │ │ ├── rs1.blk │ │ ├── rs10.blk │ │ ├── rs11.blk │ │ ├── rs12.blk │ │ ├── rs13.blk │ │ ├── rs14.blk │ │ ├── rs15.blk │ │ ├── rs16.blk │ │ ├── rs17.blk │ │ ├── rs18.blk │ │ ├── rs19.blk │ │ ├── rs2.blk │ │ ├── rs20.blk │ │ ├── rs21.blk │ │ ├── rs22.blk │ │ ├── rs23.blk │ │ ├── rs24.blk │ │ ├── rs25.blk │ │ ├── rs26.blk │ │ ├── rs27.blk │ │ ├── rs28.blk │ │ ├── rs29.blk │ │ ├── rs3.blk │ │ ├── rs30.blk │ │ ├── rs31.blk │ │ ├── rs32.blk │ │ ├── rs33.blk │ │ ├── rs34.blk │ │ ├── rs35.blk │ │ ├── rs36.blk │ │ ├── rs37.blk │ │ ├── rs38.blk │ │ ├── rs39.blk │ │ ├── rs4.blk │ │ ├── rs40.blk │ │ ├── rs41.blk │ │ ├── rs42.blk │ │ ├── rs43.blk │ │ ├── rs44.blk │ │ ├── rs45.blk │ │ ├── rs46.blk │ │ ├── rs47.blk │ │ ├── rs48.blk │ │ ├── rs49.blk │ │ ├── rs5.blk │ │ ├── rs50.blk │ │ ├── rs51.blk │ │ ├── rs52.blk │ │ ├── rs53.blk │ │ ├── rs54.blk │ │ ├── rs55.blk │ │ ├── rs56.blk │ │ ├── rs57.blk │ │ ├── rs58.blk │ │ ├── rs59.blk │ │ ├── rs6.blk │ │ ├── rs60.blk │ │ ├── rs61.blk │ │ ├── rs62.blk │ │ ├── rs63.blk │ │ ├── rs64.blk │ │ ├── rs65.blk │ │ ├── rs66.blk │ │ ├── rs67.blk │ │ ├── rs68.blk │ │ ├── rs69.blk │ │ ├── rs7.blk │ │ ├── rs70.blk │ │ ├── rs71.blk │ │ ├── rs72.blk │ │ ├── rs73.blk │ │ ├── rs74.blk │ │ ├── rs75.blk │ │ ├── rs76.blk │ │ ├── rs77.blk │ │ ├── rs78.blk │ │ ├── rs79.blk │ │ ├── rs8.blk │ │ ├── rs80.blk │ │ ├── rs81.blk │ │ ├── rs82.blk │ │ ├── rs83.blk │ │ ├── rs84.blk │ │ ├── rs85.blk │ │ ├── rs86.blk │ │ ├── rs87.blk │ │ ├── rs88.blk │ │ ├── rs89.blk │ │ ├── rs9.blk │ │ ├── rs90.blk │ │ ├── rs91.blk │ │ ├── rs92.blk │ │ ├── rs93.blk │ │ ├── rs94.blk │ │ ├── rs95.blk │ │ └── rs96.blk │ └── sort │ │ ├── res │ │ ├── rs0.blk │ │ ├── rs1.blk │ │ ├── rs10.blk │ │ ├── rs11.blk │ │ ├── rs12.blk │ │ ├── rs13.blk │ │ ├── rs14.blk │ │ ├── rs15.blk │ │ ├── rs16.blk │ │ ├── rs17.blk │ │ ├── rs18.blk │ │ ├── rs19.blk │ │ ├── rs2.blk │ │ ├── rs20.blk │ │ ├── rs21.blk │ │ ├── rs22.blk │ │ ├── rs23.blk │ │ ├── rs24.blk │ │ ├── rs25.blk │ │ ├── rs26.blk │ │ ├── rs27.blk │ │ ├── rs28.blk │ │ ├── rs29.blk │ │ ├── rs3.blk │ │ ├── rs30.blk │ │ ├── rs31.blk │ │ ├── rs32.blk │ │ ├── rs33.blk │ │ ├── rs34.blk │ │ ├── rs35.blk │ │ ├── rs36.blk │ │ ├── rs37.blk │ │ ├── rs38.blk │ │ ├── rs39.blk │ │ ├── rs4.blk │ │ ├── rs40.blk │ │ ├── rs41.blk │ │ ├── rs42.blk │ │ ├── rs43.blk │ │ ├── rs44.blk │ │ ├── rs45.blk │ │ ├── rs46.blk │ │ ├── rs47.blk │ │ ├── rs48.blk │ │ ├── rs49.blk │ │ ├── rs5.blk │ │ ├── rs50.blk │ │ ├── rs51.blk │ │ ├── rs52.blk │ │ ├── rs53.blk │ │ ├── rs54.blk │ │ ├── rs55.blk │ │ ├── rs56.blk │ │ ├── rs57.blk │ │ ├── rs58.blk │ │ ├── rs59.blk │ │ ├── rs6.blk │ │ ├── rs60.blk │ │ ├── rs61.blk │ │ ├── rs62.blk │ │ ├── rs63.blk │ │ ├── rs64.blk │ │ ├── rs65.blk │ │ ├── rs66.blk │ │ ├── rs67.blk │ │ ├── rs68.blk │ │ ├── rs69.blk │ │ ├── rs7.blk │ │ ├── rs70.blk │ │ ├── rs71.blk │ │ ├── rs72.blk │ │ ├── rs73.blk │ │ ├── rs74.blk │ │ ├── rs75.blk │ │ ├── rs76.blk │ │ ├── rs77.blk │ │ ├── rs78.blk │ │ ├── rs79.blk │ │ ├── rs8.blk │ │ ├── rs80.blk │ │ ├── rs81.blk │ │ ├── rs82.blk │ │ ├── rs83.blk │ │ ├── rs84.blk │ │ ├── rs85.blk │ │ ├── rs86.blk │ │ ├── rs87.blk │ │ ├── rs88.blk │ │ ├── rs89.blk │ │ ├── rs9.blk │ │ ├── rs90.blk │ │ ├── rs91.blk │ │ ├── rs92.blk │ │ ├── rs93.blk │ │ ├── rs94.blk │ │ ├── rs95.blk │ │ └── rs96.blk │ │ └── sort │ │ ├── r0.blk │ │ ├── r1.blk │ │ ├── r10.blk │ │ ├── r11.blk │ │ ├── r12.blk │ │ ├── r13.blk │ │ ├── r14.blk │ │ ├── r15.blk │ │ ├── r2.blk │ │ ├── r3.blk │ │ ├── r4.blk │ │ ├── r5.blk │ │ ├── r6.blk │ │ ├── r7.blk │ │ ├── r8.blk │ │ ├── r9.blk │ │ ├── s0.blk │ │ ├── s1.blk │ │ ├── s10.blk │ │ ├── s11.blk │ │ ├── s12.blk │ │ ├── s13.blk │ │ ├── s14.blk │ │ ├── s15.blk │ │ ├── s16.blk │ │ ├── s17.blk │ │ ├── s18.blk │ │ ├── s19.blk │ │ ├── s2.blk │ │ ├── s20.blk │ │ ├── s21.blk │ │ ├── s22.blk │ │ ├── s23.blk │ │ ├── s24.blk │ │ ├── s25.blk │ │ ├── s26.blk │ │ ├── s27.blk │ │ ├── s28.blk │ │ ├── s29.blk │ │ ├── s3.blk │ │ ├── s30.blk │ │ ├── s31.blk │ │ ├── s4.blk │ │ ├── s5.blk │ │ ├── s6.blk │ │ ├── s7.blk │ │ ├── s8.blk │ │ └── s9.blk ├── project │ ├── r0.blk │ ├── r1.blk │ └── r2.blk ├── relation │ ├── r0.blk │ ├── r1.blk │ ├── r10.blk │ ├── r11.blk │ ├── r12.blk │ ├── r13.blk │ ├── r14.blk │ ├── r15.blk │ ├── r2.blk │ ├── r3.blk │ ├── r4.blk │ ├── r5.blk │ ├── r6.blk │ ├── r7.blk │ ├── r8.blk │ ├── r9.blk │ ├── s0.blk │ ├── s1.blk │ ├── s10.blk │ ├── s11.blk │ ├── s12.blk │ ├── s13.blk │ ├── s14.blk │ ├── s15.blk │ ├── s16.blk │ ├── s17.blk │ ├── s18.blk │ ├── s19.blk │ ├── s2.blk │ ├── s20.blk │ ├── s21.blk │ ├── s22.blk │ ├── s23.blk │ ├── s24.blk │ ├── s25.blk │ ├── s26.blk │ ├── s27.blk │ ├── s28.blk │ ├── s29.blk │ ├── s3.blk │ ├── s30.blk │ ├── s31.blk │ ├── s4.blk │ ├── s5.blk │ ├── s6.blk │ ├── s7.blk │ ├── s8.blk │ └── s9.blk └── select │ ├── r0.blk │ ├── s0.blk │ └── s1.blk ├── extmem.py ├── gui.py ├── query_optimize.py └── relation_operate.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 哈工大20年春季数据库系统实验 2 | ## 实验一:数据库系统应用开发 3 | ## 实验二:数据库管理系统实现 -------------------------------------------------------------------------------- /lab1/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ -------------------------------------------------------------------------------- /lab1/README.md: -------------------------------------------------------------------------------- 1 | # 实验一:数据库系统应用开发 2 | ## 完成部分 3 | - 所有基本功能 4 | - 插入与删除合法元素 5 | - 插入与删除空值 6 | - 插入重复值、删除不存在值 7 | - 参照完整性约束实现 8 | - 连接查询、分组查询、嵌套查询:体现分组和Having语句 9 | - 触发器实现参照完整性约束 10 | - 事务管理实现转账操作 11 | - 界面友好 12 | - 用户少输入,操作便捷 13 | - 多选项框,保证健壮性 14 | - 非法操作警告弹窗,提示信息完整 15 | - 菜单栏的设计,使得设计的功能模块很合理 16 | ## 如何运行 17 | - 开发环境:Pycharm 2020.1 专业版 18 | - 语言与平台:Python3.6 Anaconda 19 | - 运行程序 20 | - 以db_lab作为项目目录 21 | - 运行main.py即可 22 | ## 运行截图 23 | - 主界面![主界面](./src/主界面运行截图.png) 24 | - 视图创建界面![视图创建界面](./src/视图创建界面.png) 25 | - 事务管理界面![事务管理界面](./src/事务管理界面.png) -------------------------------------------------------------------------------- /lab1/gui/gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'gui.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.14.1 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | 10 | from PyQt5 import QtCore, QtGui, QtWidgets 11 | 12 | 13 | class Ui_MainWindow(object): 14 | def setupUi(self, MainWindow): 15 | MainWindow.setObjectName("MainWindow") 16 | MainWindow.resize(951, 631) 17 | MainWindow.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) 18 | self.centralwidget = QtWidgets.QWidget(MainWindow) 19 | self.centralwidget.setObjectName("centralwidget") 20 | self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.centralwidget) 21 | self.verticalLayout_9.setObjectName("verticalLayout_9") 22 | self.horizontalLayout_10 = QtWidgets.QHBoxLayout() 23 | self.horizontalLayout_10.setObjectName("horizontalLayout_10") 24 | self.frame_11 = QtWidgets.QFrame(self.centralwidget) 25 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 26 | sizePolicy.setHorizontalStretch(1) 27 | sizePolicy.setVerticalStretch(0) 28 | sizePolicy.setHeightForWidth(self.frame_11.sizePolicy().hasHeightForWidth()) 29 | self.frame_11.setSizePolicy(sizePolicy) 30 | self.frame_11.setFrameShape(QtWidgets.QFrame.StyledPanel) 31 | self.frame_11.setFrameShadow(QtWidgets.QFrame.Raised) 32 | self.frame_11.setObjectName("frame_11") 33 | self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.frame_11) 34 | self.verticalLayout_11.setObjectName("verticalLayout_11") 35 | self.label_23 = QtWidgets.QLabel(self.frame_11) 36 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 37 | sizePolicy.setHorizontalStretch(1) 38 | sizePolicy.setVerticalStretch(0) 39 | sizePolicy.setHeightForWidth(self.label_23.sizePolicy().hasHeightForWidth()) 40 | self.label_23.setSizePolicy(sizePolicy) 41 | self.label_23.setStyleSheet("") 42 | self.label_23.setFrameShape(QtWidgets.QFrame.Box) 43 | self.label_23.setFrameShadow(QtWidgets.QFrame.Plain) 44 | self.label_23.setAlignment(QtCore.Qt.AlignCenter) 45 | self.label_23.setObjectName("label_23") 46 | self.verticalLayout_11.addWidget(self.label_23) 47 | self.add_trigger = QtWidgets.QRadioButton(self.frame_11) 48 | self.add_trigger.setObjectName("add_trigger") 49 | self.verticalLayout_11.addWidget(self.add_trigger) 50 | self.horizontalLayout_10.addWidget(self.frame_11) 51 | self.frame = QtWidgets.QFrame(self.centralwidget) 52 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 53 | sizePolicy.setHorizontalStretch(2) 54 | sizePolicy.setVerticalStretch(0) 55 | sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) 56 | self.frame.setSizePolicy(sizePolicy) 57 | self.frame.setFrameShape(QtWidgets.QFrame.Box) 58 | self.frame.setFrameShadow(QtWidgets.QFrame.Raised) 59 | self.frame.setObjectName("frame") 60 | self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) 61 | self.verticalLayout.setObjectName("verticalLayout") 62 | self.label = QtWidgets.QLabel(self.frame) 63 | self.label.setObjectName("label") 64 | self.verticalLayout.addWidget(self.label) 65 | self.line = QtWidgets.QFrame(self.frame) 66 | self.line.setFrameShape(QtWidgets.QFrame.HLine) 67 | self.line.setFrameShadow(QtWidgets.QFrame.Sunken) 68 | self.line.setObjectName("line") 69 | self.verticalLayout.addWidget(self.line) 70 | self.horizontalLayout = QtWidgets.QHBoxLayout() 71 | self.horizontalLayout.setObjectName("horizontalLayout") 72 | self.label_2 = QtWidgets.QLabel(self.frame) 73 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 74 | sizePolicy.setHorizontalStretch(2) 75 | sizePolicy.setVerticalStretch(0) 76 | sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) 77 | self.label_2.setSizePolicy(sizePolicy) 78 | self.label_2.setObjectName("label_2") 79 | self.horizontalLayout.addWidget(self.label_2) 80 | self.stu_num = QtWidgets.QLineEdit(self.frame) 81 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 82 | sizePolicy.setHorizontalStretch(5) 83 | sizePolicy.setVerticalStretch(0) 84 | sizePolicy.setHeightForWidth(self.stu_num.sizePolicy().hasHeightForWidth()) 85 | self.stu_num.setSizePolicy(sizePolicy) 86 | self.stu_num.setObjectName("stu_num") 87 | self.horizontalLayout.addWidget(self.stu_num) 88 | self.verticalLayout.addLayout(self.horizontalLayout) 89 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 90 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 91 | self.label_3 = QtWidgets.QLabel(self.frame) 92 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 93 | sizePolicy.setHorizontalStretch(2) 94 | sizePolicy.setVerticalStretch(0) 95 | sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth()) 96 | self.label_3.setSizePolicy(sizePolicy) 97 | self.label_3.setObjectName("label_3") 98 | self.horizontalLayout_2.addWidget(self.label_3) 99 | self.stu_name = QtWidgets.QLineEdit(self.frame) 100 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 101 | sizePolicy.setHorizontalStretch(5) 102 | sizePolicy.setVerticalStretch(0) 103 | sizePolicy.setHeightForWidth(self.stu_name.sizePolicy().hasHeightForWidth()) 104 | self.stu_name.setSizePolicy(sizePolicy) 105 | self.stu_name.setObjectName("stu_name") 106 | self.horizontalLayout_2.addWidget(self.stu_name) 107 | self.verticalLayout.addLayout(self.horizontalLayout_2) 108 | self.horizontalLayout_12 = QtWidgets.QHBoxLayout() 109 | self.horizontalLayout_12.setObjectName("horizontalLayout_12") 110 | self.label_11 = QtWidgets.QLabel(self.frame) 111 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 112 | sizePolicy.setHorizontalStretch(2) 113 | sizePolicy.setVerticalStretch(0) 114 | sizePolicy.setHeightForWidth(self.label_11.sizePolicy().hasHeightForWidth()) 115 | self.label_11.setSizePolicy(sizePolicy) 116 | self.label_11.setObjectName("label_11") 117 | self.horizontalLayout_12.addWidget(self.label_11) 118 | self.class_num = QtWidgets.QLineEdit(self.frame) 119 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 120 | sizePolicy.setHorizontalStretch(5) 121 | sizePolicy.setVerticalStretch(0) 122 | sizePolicy.setHeightForWidth(self.class_num.sizePolicy().hasHeightForWidth()) 123 | self.class_num.setSizePolicy(sizePolicy) 124 | self.class_num.setObjectName("class_num") 125 | self.horizontalLayout_12.addWidget(self.class_num) 126 | self.verticalLayout.addLayout(self.horizontalLayout_12) 127 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 128 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 129 | self.stu_insert = QtWidgets.QPushButton(self.frame) 130 | self.stu_insert.setObjectName("stu_insert") 131 | self.horizontalLayout_4.addWidget(self.stu_insert) 132 | self.stu_delete = QtWidgets.QPushButton(self.frame) 133 | self.stu_delete.setObjectName("stu_delete") 134 | self.horizontalLayout_4.addWidget(self.stu_delete) 135 | self.verticalLayout.addLayout(self.horizontalLayout_4) 136 | self.horizontalLayout_10.addWidget(self.frame) 137 | self.frame_2 = QtWidgets.QFrame(self.centralwidget) 138 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 139 | sizePolicy.setHorizontalStretch(2) 140 | sizePolicy.setVerticalStretch(0) 141 | sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) 142 | self.frame_2.setSizePolicy(sizePolicy) 143 | self.frame_2.setFrameShape(QtWidgets.QFrame.Box) 144 | self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) 145 | self.frame_2.setObjectName("frame_2") 146 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame_2) 147 | self.verticalLayout_2.setObjectName("verticalLayout_2") 148 | self.label_4 = QtWidgets.QLabel(self.frame_2) 149 | self.label_4.setObjectName("label_4") 150 | self.verticalLayout_2.addWidget(self.label_4) 151 | self.line_2 = QtWidgets.QFrame(self.frame_2) 152 | self.line_2.setFrameShape(QtWidgets.QFrame.HLine) 153 | self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) 154 | self.line_2.setObjectName("line_2") 155 | self.verticalLayout_2.addWidget(self.line_2) 156 | self.horizontalLayout_6 = QtWidgets.QHBoxLayout() 157 | self.horizontalLayout_6.setObjectName("horizontalLayout_6") 158 | self.label_5 = QtWidgets.QLabel(self.frame_2) 159 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 160 | sizePolicy.setHorizontalStretch(2) 161 | sizePolicy.setVerticalStretch(0) 162 | sizePolicy.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth()) 163 | self.label_5.setSizePolicy(sizePolicy) 164 | self.label_5.setObjectName("label_5") 165 | self.horizontalLayout_6.addWidget(self.label_5) 166 | self.course_num = QtWidgets.QLineEdit(self.frame_2) 167 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 168 | sizePolicy.setHorizontalStretch(5) 169 | sizePolicy.setVerticalStretch(0) 170 | sizePolicy.setHeightForWidth(self.course_num.sizePolicy().hasHeightForWidth()) 171 | self.course_num.setSizePolicy(sizePolicy) 172 | self.course_num.setObjectName("course_num") 173 | self.horizontalLayout_6.addWidget(self.course_num) 174 | self.verticalLayout_2.addLayout(self.horizontalLayout_6) 175 | self.horizontalLayout_7 = QtWidgets.QHBoxLayout() 176 | self.horizontalLayout_7.setObjectName("horizontalLayout_7") 177 | self.label_6 = QtWidgets.QLabel(self.frame_2) 178 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 179 | sizePolicy.setHorizontalStretch(2) 180 | sizePolicy.setVerticalStretch(0) 181 | sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth()) 182 | self.label_6.setSizePolicy(sizePolicy) 183 | self.label_6.setObjectName("label_6") 184 | self.horizontalLayout_7.addWidget(self.label_6) 185 | self.course_name = QtWidgets.QLineEdit(self.frame_2) 186 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 187 | sizePolicy.setHorizontalStretch(5) 188 | sizePolicy.setVerticalStretch(0) 189 | sizePolicy.setHeightForWidth(self.course_name.sizePolicy().hasHeightForWidth()) 190 | self.course_name.setSizePolicy(sizePolicy) 191 | self.course_name.setObjectName("course_name") 192 | self.horizontalLayout_7.addWidget(self.course_name) 193 | self.verticalLayout_2.addLayout(self.horizontalLayout_7) 194 | self.horizontalLayout_13 = QtWidgets.QHBoxLayout() 195 | self.horizontalLayout_13.setObjectName("horizontalLayout_13") 196 | self.label_12 = QtWidgets.QLabel(self.frame_2) 197 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 198 | sizePolicy.setHorizontalStretch(2) 199 | sizePolicy.setVerticalStretch(0) 200 | sizePolicy.setHeightForWidth(self.label_12.sizePolicy().hasHeightForWidth()) 201 | self.label_12.setSizePolicy(sizePolicy) 202 | self.label_12.setObjectName("label_12") 203 | self.horizontalLayout_13.addWidget(self.label_12) 204 | self.teacher_num = QtWidgets.QLineEdit(self.frame_2) 205 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 206 | sizePolicy.setHorizontalStretch(5) 207 | sizePolicy.setVerticalStretch(0) 208 | sizePolicy.setHeightForWidth(self.teacher_num.sizePolicy().hasHeightForWidth()) 209 | self.teacher_num.setSizePolicy(sizePolicy) 210 | self.teacher_num.setObjectName("teacher_num") 211 | self.horizontalLayout_13.addWidget(self.teacher_num) 212 | self.verticalLayout_2.addLayout(self.horizontalLayout_13) 213 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 214 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 215 | self.course_insert = QtWidgets.QPushButton(self.frame_2) 216 | self.course_insert.setObjectName("course_insert") 217 | self.horizontalLayout_3.addWidget(self.course_insert) 218 | self.course_delete = QtWidgets.QPushButton(self.frame_2) 219 | self.course_delete.setObjectName("course_delete") 220 | self.horizontalLayout_3.addWidget(self.course_delete) 221 | self.verticalLayout_2.addLayout(self.horizontalLayout_3) 222 | self.horizontalLayout_10.addWidget(self.frame_2) 223 | self.frame_3 = QtWidgets.QFrame(self.centralwidget) 224 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 225 | sizePolicy.setHorizontalStretch(2) 226 | sizePolicy.setVerticalStretch(0) 227 | sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth()) 228 | self.frame_3.setSizePolicy(sizePolicy) 229 | self.frame_3.setFrameShape(QtWidgets.QFrame.Box) 230 | self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) 231 | self.frame_3.setObjectName("frame_3") 232 | self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_3) 233 | self.verticalLayout_3.setObjectName("verticalLayout_3") 234 | self.label_9 = QtWidgets.QLabel(self.frame_3) 235 | self.label_9.setObjectName("label_9") 236 | self.verticalLayout_3.addWidget(self.label_9) 237 | self.line_3 = QtWidgets.QFrame(self.frame_3) 238 | self.line_3.setFrameShape(QtWidgets.QFrame.HLine) 239 | self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken) 240 | self.line_3.setObjectName("line_3") 241 | self.verticalLayout_3.addWidget(self.line_3) 242 | self.horizontalLayout_8 = QtWidgets.QHBoxLayout() 243 | self.horizontalLayout_8.setObjectName("horizontalLayout_8") 244 | self.label_7 = QtWidgets.QLabel(self.frame_3) 245 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 246 | sizePolicy.setHorizontalStretch(2) 247 | sizePolicy.setVerticalStretch(0) 248 | sizePolicy.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth()) 249 | self.label_7.setSizePolicy(sizePolicy) 250 | self.label_7.setObjectName("label_7") 251 | self.horizontalLayout_8.addWidget(self.label_7) 252 | self.sc_snum = QtWidgets.QLineEdit(self.frame_3) 253 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 254 | sizePolicy.setHorizontalStretch(5) 255 | sizePolicy.setVerticalStretch(0) 256 | sizePolicy.setHeightForWidth(self.sc_snum.sizePolicy().hasHeightForWidth()) 257 | self.sc_snum.setSizePolicy(sizePolicy) 258 | self.sc_snum.setObjectName("sc_snum") 259 | self.horizontalLayout_8.addWidget(self.sc_snum) 260 | self.verticalLayout_3.addLayout(self.horizontalLayout_8) 261 | self.horizontalLayout_9 = QtWidgets.QHBoxLayout() 262 | self.horizontalLayout_9.setObjectName("horizontalLayout_9") 263 | self.label_8 = QtWidgets.QLabel(self.frame_3) 264 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 265 | sizePolicy.setHorizontalStretch(2) 266 | sizePolicy.setVerticalStretch(0) 267 | sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) 268 | self.label_8.setSizePolicy(sizePolicy) 269 | self.label_8.setObjectName("label_8") 270 | self.horizontalLayout_9.addWidget(self.label_8) 271 | self.sc_cnum = QtWidgets.QLineEdit(self.frame_3) 272 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 273 | sizePolicy.setHorizontalStretch(5) 274 | sizePolicy.setVerticalStretch(0) 275 | sizePolicy.setHeightForWidth(self.sc_cnum.sizePolicy().hasHeightForWidth()) 276 | self.sc_cnum.setSizePolicy(sizePolicy) 277 | self.sc_cnum.setObjectName("sc_cnum") 278 | self.horizontalLayout_9.addWidget(self.sc_cnum) 279 | self.verticalLayout_3.addLayout(self.horizontalLayout_9) 280 | self.horizontalLayout_11 = QtWidgets.QHBoxLayout() 281 | self.horizontalLayout_11.setObjectName("horizontalLayout_11") 282 | self.label_10 = QtWidgets.QLabel(self.frame_3) 283 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 284 | sizePolicy.setHorizontalStretch(2) 285 | sizePolicy.setVerticalStretch(0) 286 | sizePolicy.setHeightForWidth(self.label_10.sizePolicy().hasHeightForWidth()) 287 | self.label_10.setSizePolicy(sizePolicy) 288 | self.label_10.setObjectName("label_10") 289 | self.horizontalLayout_11.addWidget(self.label_10) 290 | self.sc_grade = QtWidgets.QLineEdit(self.frame_3) 291 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) 292 | sizePolicy.setHorizontalStretch(5) 293 | sizePolicy.setVerticalStretch(0) 294 | sizePolicy.setHeightForWidth(self.sc_grade.sizePolicy().hasHeightForWidth()) 295 | self.sc_grade.setSizePolicy(sizePolicy) 296 | self.sc_grade.setObjectName("sc_grade") 297 | self.horizontalLayout_11.addWidget(self.sc_grade) 298 | self.verticalLayout_3.addLayout(self.horizontalLayout_11) 299 | self.horizontalLayout_5 = QtWidgets.QHBoxLayout() 300 | self.horizontalLayout_5.setObjectName("horizontalLayout_5") 301 | self.sc_insert = QtWidgets.QPushButton(self.frame_3) 302 | self.sc_insert.setObjectName("sc_insert") 303 | self.horizontalLayout_5.addWidget(self.sc_insert) 304 | self.sc_delete = QtWidgets.QPushButton(self.frame_3) 305 | self.sc_delete.setObjectName("sc_delete") 306 | self.horizontalLayout_5.addWidget(self.sc_delete) 307 | self.verticalLayout_3.addLayout(self.horizontalLayout_5) 308 | self.horizontalLayout_10.addWidget(self.frame_3) 309 | self.verticalLayout_9.addLayout(self.horizontalLayout_10) 310 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 311 | self.verticalLayout_9.addItem(spacerItem) 312 | self.line_10 = QtWidgets.QFrame(self.centralwidget) 313 | self.line_10.setFrameShape(QtWidgets.QFrame.HLine) 314 | self.line_10.setFrameShadow(QtWidgets.QFrame.Sunken) 315 | self.line_10.setObjectName("line_10") 316 | self.verticalLayout_9.addWidget(self.line_10) 317 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 318 | self.verticalLayout_9.addItem(spacerItem1) 319 | self.horizontalLayout_17 = QtWidgets.QHBoxLayout() 320 | self.horizontalLayout_17.setObjectName("horizontalLayout_17") 321 | self.label_24 = QtWidgets.QLabel(self.centralwidget) 322 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 323 | sizePolicy.setHorizontalStretch(1) 324 | sizePolicy.setVerticalStretch(0) 325 | sizePolicy.setHeightForWidth(self.label_24.sizePolicy().hasHeightForWidth()) 326 | self.label_24.setSizePolicy(sizePolicy) 327 | self.label_24.setFrameShape(QtWidgets.QFrame.Box) 328 | self.label_24.setAlignment(QtCore.Qt.AlignCenter) 329 | self.label_24.setObjectName("label_24") 330 | self.horizontalLayout_17.addWidget(self.label_24) 331 | self.frame_4 = QtWidgets.QFrame(self.centralwidget) 332 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 333 | sizePolicy.setHorizontalStretch(2) 334 | sizePolicy.setVerticalStretch(0) 335 | sizePolicy.setHeightForWidth(self.frame_4.sizePolicy().hasHeightForWidth()) 336 | self.frame_4.setSizePolicy(sizePolicy) 337 | self.frame_4.setFrameShape(QtWidgets.QFrame.Box) 338 | self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) 339 | self.frame_4.setLineWidth(1) 340 | self.frame_4.setObjectName("frame_4") 341 | self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_4) 342 | self.verticalLayout_4.setObjectName("verticalLayout_4") 343 | self.label_13 = QtWidgets.QLabel(self.frame_4) 344 | self.label_13.setObjectName("label_13") 345 | self.verticalLayout_4.addWidget(self.label_13) 346 | self.line_4 = QtWidgets.QFrame(self.frame_4) 347 | self.line_4.setFrameShape(QtWidgets.QFrame.HLine) 348 | self.line_4.setFrameShadow(QtWidgets.QFrame.Sunken) 349 | self.line_4.setObjectName("line_4") 350 | self.verticalLayout_4.addWidget(self.line_4) 351 | self.horizontalLayout_14 = QtWidgets.QHBoxLayout() 352 | self.horizontalLayout_14.setObjectName("horizontalLayout_14") 353 | self.label_14 = QtWidgets.QLabel(self.frame_4) 354 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 355 | sizePolicy.setHorizontalStretch(2) 356 | sizePolicy.setVerticalStretch(0) 357 | sizePolicy.setHeightForWidth(self.label_14.sizePolicy().hasHeightForWidth()) 358 | self.label_14.setSizePolicy(sizePolicy) 359 | self.label_14.setObjectName("label_14") 360 | self.horizontalLayout_14.addWidget(self.label_14) 361 | self.sc_stu_count = QtWidgets.QSpinBox(self.frame_4) 362 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 363 | sizePolicy.setHorizontalStretch(5) 364 | sizePolicy.setVerticalStretch(0) 365 | sizePolicy.setHeightForWidth(self.sc_stu_count.sizePolicy().hasHeightForWidth()) 366 | self.sc_stu_count.setSizePolicy(sizePolicy) 367 | self.sc_stu_count.setObjectName("sc_stu_count") 368 | self.horizontalLayout_14.addWidget(self.sc_stu_count) 369 | self.verticalLayout_4.addLayout(self.horizontalLayout_14) 370 | self.name_query = QtWidgets.QPushButton(self.frame_4) 371 | self.name_query.setObjectName("name_query") 372 | self.verticalLayout_4.addWidget(self.name_query) 373 | self.horizontalLayout_17.addWidget(self.frame_4) 374 | self.frame_5 = QtWidgets.QFrame(self.centralwidget) 375 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 376 | sizePolicy.setHorizontalStretch(2) 377 | sizePolicy.setVerticalStretch(0) 378 | sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth()) 379 | self.frame_5.setSizePolicy(sizePolicy) 380 | self.frame_5.setFrameShape(QtWidgets.QFrame.Box) 381 | self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised) 382 | self.frame_5.setObjectName("frame_5") 383 | self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.frame_5) 384 | self.verticalLayout_5.setObjectName("verticalLayout_5") 385 | self.label_15 = QtWidgets.QLabel(self.frame_5) 386 | self.label_15.setObjectName("label_15") 387 | self.verticalLayout_5.addWidget(self.label_15) 388 | self.line_5 = QtWidgets.QFrame(self.frame_5) 389 | self.line_5.setFrameShape(QtWidgets.QFrame.HLine) 390 | self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken) 391 | self.line_5.setObjectName("line_5") 392 | self.verticalLayout_5.addWidget(self.line_5) 393 | self.horizontalLayout_16 = QtWidgets.QHBoxLayout() 394 | self.horizontalLayout_16.setObjectName("horizontalLayout_16") 395 | self.label_16 = QtWidgets.QLabel(self.frame_5) 396 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 397 | sizePolicy.setHorizontalStretch(2) 398 | sizePolicy.setVerticalStretch(0) 399 | sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth()) 400 | self.label_16.setSizePolicy(sizePolicy) 401 | self.label_16.setObjectName("label_16") 402 | self.horizontalLayout_16.addWidget(self.label_16) 403 | self.c_num_combobox = QtWidgets.QComboBox(self.frame_5) 404 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 405 | sizePolicy.setHorizontalStretch(5) 406 | sizePolicy.setVerticalStretch(0) 407 | sizePolicy.setHeightForWidth(self.c_num_combobox.sizePolicy().hasHeightForWidth()) 408 | self.c_num_combobox.setSizePolicy(sizePolicy) 409 | self.c_num_combobox.setObjectName("c_num_combobox") 410 | self.horizontalLayout_16.addWidget(self.c_num_combobox) 411 | self.verticalLayout_5.addLayout(self.horizontalLayout_16) 412 | self.name_query_by_cnum = QtWidgets.QPushButton(self.frame_5) 413 | self.name_query_by_cnum.setObjectName("name_query_by_cnum") 414 | self.verticalLayout_5.addWidget(self.name_query_by_cnum) 415 | self.horizontalLayout_17.addWidget(self.frame_5) 416 | self.frame_6 = QtWidgets.QFrame(self.centralwidget) 417 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 418 | sizePolicy.setHorizontalStretch(2) 419 | sizePolicy.setVerticalStretch(0) 420 | sizePolicy.setHeightForWidth(self.frame_6.sizePolicy().hasHeightForWidth()) 421 | self.frame_6.setSizePolicy(sizePolicy) 422 | self.frame_6.setFrameShape(QtWidgets.QFrame.Box) 423 | self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised) 424 | self.frame_6.setObjectName("frame_6") 425 | self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.frame_6) 426 | self.verticalLayout_6.setObjectName("verticalLayout_6") 427 | self.label_18 = QtWidgets.QLabel(self.frame_6) 428 | self.label_18.setObjectName("label_18") 429 | self.verticalLayout_6.addWidget(self.label_18) 430 | self.line_8 = QtWidgets.QFrame(self.frame_6) 431 | self.line_8.setFrameShape(QtWidgets.QFrame.HLine) 432 | self.line_8.setFrameShadow(QtWidgets.QFrame.Sunken) 433 | self.line_8.setObjectName("line_8") 434 | self.verticalLayout_6.addWidget(self.line_8) 435 | self.horizontalLayout_19 = QtWidgets.QHBoxLayout() 436 | self.horizontalLayout_19.setObjectName("horizontalLayout_19") 437 | self.label_17 = QtWidgets.QLabel(self.frame_6) 438 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 439 | sizePolicy.setHorizontalStretch(2) 440 | sizePolicy.setVerticalStretch(0) 441 | sizePolicy.setHeightForWidth(self.label_17.sizePolicy().hasHeightForWidth()) 442 | self.label_17.setSizePolicy(sizePolicy) 443 | self.label_17.setObjectName("label_17") 444 | self.horizontalLayout_19.addWidget(self.label_17) 445 | self.stu_name_combobox = QtWidgets.QComboBox(self.frame_6) 446 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 447 | sizePolicy.setHorizontalStretch(5) 448 | sizePolicy.setVerticalStretch(0) 449 | sizePolicy.setHeightForWidth(self.stu_name_combobox.sizePolicy().hasHeightForWidth()) 450 | self.stu_name_combobox.setSizePolicy(sizePolicy) 451 | self.stu_name_combobox.setObjectName("stu_name_combobox") 452 | self.horizontalLayout_19.addWidget(self.stu_name_combobox) 453 | self.verticalLayout_6.addLayout(self.horizontalLayout_19) 454 | self.get_avg_grade = QtWidgets.QPushButton(self.frame_6) 455 | self.get_avg_grade.setObjectName("get_avg_grade") 456 | self.verticalLayout_6.addWidget(self.get_avg_grade) 457 | self.horizontalLayout_17.addWidget(self.frame_6) 458 | self.verticalLayout_9.addLayout(self.horizontalLayout_17) 459 | spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 460 | self.verticalLayout_9.addItem(spacerItem2) 461 | self.line_9 = QtWidgets.QFrame(self.centralwidget) 462 | self.line_9.setFrameShape(QtWidgets.QFrame.HLine) 463 | self.line_9.setFrameShadow(QtWidgets.QFrame.Sunken) 464 | self.line_9.setObjectName("line_9") 465 | self.verticalLayout_9.addWidget(self.line_9) 466 | spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 467 | self.verticalLayout_9.addItem(spacerItem3) 468 | self.horizontalLayout_20 = QtWidgets.QHBoxLayout() 469 | self.horizontalLayout_20.setObjectName("horizontalLayout_20") 470 | self.label_25 = QtWidgets.QLabel(self.centralwidget) 471 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 472 | sizePolicy.setHorizontalStretch(1) 473 | sizePolicy.setVerticalStretch(0) 474 | sizePolicy.setHeightForWidth(self.label_25.sizePolicy().hasHeightForWidth()) 475 | self.label_25.setSizePolicy(sizePolicy) 476 | self.label_25.setFrameShape(QtWidgets.QFrame.Box) 477 | self.label_25.setAlignment(QtCore.Qt.AlignCenter) 478 | self.label_25.setObjectName("label_25") 479 | self.horizontalLayout_20.addWidget(self.label_25) 480 | self.frame_9 = QtWidgets.QFrame(self.centralwidget) 481 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 482 | sizePolicy.setHorizontalStretch(1) 483 | sizePolicy.setVerticalStretch(0) 484 | sizePolicy.setHeightForWidth(self.frame_9.sizePolicy().hasHeightForWidth()) 485 | self.frame_9.setSizePolicy(sizePolicy) 486 | self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel) 487 | self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised) 488 | self.frame_9.setObjectName("frame_9") 489 | self.horizontalLayout_20.addWidget(self.frame_9) 490 | self.frame_7 = QtWidgets.QFrame(self.centralwidget) 491 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 492 | sizePolicy.setHorizontalStretch(2) 493 | sizePolicy.setVerticalStretch(0) 494 | sizePolicy.setHeightForWidth(self.frame_7.sizePolicy().hasHeightForWidth()) 495 | self.frame_7.setSizePolicy(sizePolicy) 496 | self.frame_7.setFrameShape(QtWidgets.QFrame.Box) 497 | self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised) 498 | self.frame_7.setObjectName("frame_7") 499 | self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.frame_7) 500 | self.verticalLayout_7.setObjectName("verticalLayout_7") 501 | self.label_20 = QtWidgets.QLabel(self.frame_7) 502 | self.label_20.setObjectName("label_20") 503 | self.verticalLayout_7.addWidget(self.label_20) 504 | self.line_6 = QtWidgets.QFrame(self.frame_7) 505 | self.line_6.setFrameShape(QtWidgets.QFrame.HLine) 506 | self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken) 507 | self.line_6.setObjectName("line_6") 508 | self.verticalLayout_7.addWidget(self.line_6) 509 | self.horizontalLayout_15 = QtWidgets.QHBoxLayout() 510 | self.horizontalLayout_15.setObjectName("horizontalLayout_15") 511 | self.label_19 = QtWidgets.QLabel(self.frame_7) 512 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 513 | sizePolicy.setHorizontalStretch(2) 514 | sizePolicy.setVerticalStretch(0) 515 | sizePolicy.setHeightForWidth(self.label_19.sizePolicy().hasHeightForWidth()) 516 | self.label_19.setSizePolicy(sizePolicy) 517 | self.label_19.setObjectName("label_19") 518 | self.horizontalLayout_15.addWidget(self.label_19) 519 | self.cs_department = QtWidgets.QComboBox(self.frame_7) 520 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 521 | sizePolicy.setHorizontalStretch(5) 522 | sizePolicy.setVerticalStretch(0) 523 | sizePolicy.setHeightForWidth(self.cs_department.sizePolicy().hasHeightForWidth()) 524 | self.cs_department.setSizePolicy(sizePolicy) 525 | self.cs_department.setObjectName("cs_department") 526 | self.cs_department.addItem("") 527 | self.cs_department.addItem("") 528 | self.cs_department.addItem("") 529 | self.horizontalLayout_15.addWidget(self.cs_department) 530 | self.verticalLayout_7.addLayout(self.horizontalLayout_15) 531 | self.create_view = QtWidgets.QPushButton(self.frame_7) 532 | self.create_view.setObjectName("create_view") 533 | self.verticalLayout_7.addWidget(self.create_view) 534 | self.horizontalLayout_20.addWidget(self.frame_7) 535 | self.frame_8 = QtWidgets.QFrame(self.centralwidget) 536 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 537 | sizePolicy.setHorizontalStretch(2) 538 | sizePolicy.setVerticalStretch(0) 539 | sizePolicy.setHeightForWidth(self.frame_8.sizePolicy().hasHeightForWidth()) 540 | self.frame_8.setSizePolicy(sizePolicy) 541 | self.frame_8.setFrameShape(QtWidgets.QFrame.Box) 542 | self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised) 543 | self.frame_8.setObjectName("frame_8") 544 | self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.frame_8) 545 | self.verticalLayout_8.setObjectName("verticalLayout_8") 546 | self.label_21 = QtWidgets.QLabel(self.frame_8) 547 | self.label_21.setObjectName("label_21") 548 | self.verticalLayout_8.addWidget(self.label_21) 549 | self.line_7 = QtWidgets.QFrame(self.frame_8) 550 | self.line_7.setFrameShape(QtWidgets.QFrame.HLine) 551 | self.line_7.setFrameShadow(QtWidgets.QFrame.Sunken) 552 | self.line_7.setObjectName("line_7") 553 | self.verticalLayout_8.addWidget(self.line_7) 554 | self.horizontalLayout_18 = QtWidgets.QHBoxLayout() 555 | self.horizontalLayout_18.setObjectName("horizontalLayout_18") 556 | self.label_22 = QtWidgets.QLabel(self.frame_8) 557 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 558 | sizePolicy.setHorizontalStretch(2) 559 | sizePolicy.setVerticalStretch(0) 560 | sizePolicy.setHeightForWidth(self.label_22.sizePolicy().hasHeightForWidth()) 561 | self.label_22.setSizePolicy(sizePolicy) 562 | self.label_22.setObjectName("label_22") 563 | self.horizontalLayout_18.addWidget(self.label_22) 564 | self.cs_index = QtWidgets.QComboBox(self.frame_8) 565 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 566 | sizePolicy.setHorizontalStretch(5) 567 | sizePolicy.setVerticalStretch(0) 568 | sizePolicy.setHeightForWidth(self.cs_index.sizePolicy().hasHeightForWidth()) 569 | self.cs_index.setSizePolicy(sizePolicy) 570 | self.cs_index.setObjectName("cs_index") 571 | self.cs_index.addItem("") 572 | self.cs_index.addItem("") 573 | self.cs_index.addItem("") 574 | self.cs_index.addItem("") 575 | self.horizontalLayout_18.addWidget(self.cs_index) 576 | self.verticalLayout_8.addLayout(self.horizontalLayout_18) 577 | self.create_index = QtWidgets.QPushButton(self.frame_8) 578 | self.create_index.setObjectName("create_index") 579 | self.verticalLayout_8.addWidget(self.create_index) 580 | self.horizontalLayout_20.addWidget(self.frame_8) 581 | self.frame_10 = QtWidgets.QFrame(self.centralwidget) 582 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 583 | sizePolicy.setHorizontalStretch(1) 584 | sizePolicy.setVerticalStretch(0) 585 | sizePolicy.setHeightForWidth(self.frame_10.sizePolicy().hasHeightForWidth()) 586 | self.frame_10.setSizePolicy(sizePolicy) 587 | self.frame_10.setFrameShape(QtWidgets.QFrame.NoFrame) 588 | self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised) 589 | self.frame_10.setObjectName("frame_10") 590 | self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.frame_10) 591 | self.verticalLayout_10.setObjectName("verticalLayout_10") 592 | self.horizontalLayout_20.addWidget(self.frame_10) 593 | self.verticalLayout_9.addLayout(self.horizontalLayout_20) 594 | MainWindow.setCentralWidget(self.centralwidget) 595 | self.menuBar = QtWidgets.QMenuBar(MainWindow) 596 | self.menuBar.setGeometry(QtCore.QRect(0, 0, 951, 26)) 597 | self.menuBar.setObjectName("menuBar") 598 | self.stu_menu = QtWidgets.QMenu(self.menuBar) 599 | self.stu_menu.setObjectName("stu_menu") 600 | self.teacher_menu = QtWidgets.QMenu(self.menuBar) 601 | self.teacher_menu.setObjectName("teacher_menu") 602 | self.sc_menu = QtWidgets.QMenu(self.menuBar) 603 | self.sc_menu.setObjectName("sc_menu") 604 | self.menu_more = QtWidgets.QMenu(self.menuBar) 605 | self.menu_more.setObjectName("menu_more") 606 | self.menu = QtWidgets.QMenu(self.menuBar) 607 | self.menu.setObjectName("menu") 608 | MainWindow.setMenuBar(self.menuBar) 609 | self.action1 = QtWidgets.QAction(MainWindow) 610 | self.action1.setObjectName("action1") 611 | self.action1_2 = QtWidgets.QAction(MainWindow) 612 | self.action1_2.setObjectName("action1_2") 613 | self.action2 = QtWidgets.QAction(MainWindow) 614 | self.action2.setObjectName("action2") 615 | self.action3 = QtWidgets.QAction(MainWindow) 616 | self.action3.setObjectName("action3") 617 | self.stu_insert_act = QtWidgets.QAction(MainWindow) 618 | self.stu_insert_act.setObjectName("stu_insert_act") 619 | self.stu_delete_act = QtWidgets.QAction(MainWindow) 620 | self.stu_delete_act.setObjectName("stu_delete_act") 621 | self.action1_4 = QtWidgets.QAction(MainWindow) 622 | self.action1_4.setObjectName("action1_4") 623 | self.action2_3 = QtWidgets.QAction(MainWindow) 624 | self.action2_3.setObjectName("action2_3") 625 | self.action3_2 = QtWidgets.QAction(MainWindow) 626 | self.action3_2.setObjectName("action3_2") 627 | self.action1_5 = QtWidgets.QAction(MainWindow) 628 | self.action1_5.setObjectName("action1_5") 629 | self.action2_4 = QtWidgets.QAction(MainWindow) 630 | self.action2_4.setObjectName("action2_4") 631 | self.stu_ = QtWidgets.QAction(MainWindow) 632 | self.stu_.setObjectName("stu_") 633 | self.actiontodo = QtWidgets.QAction(MainWindow) 634 | self.actiontodo.setObjectName("actiontodo") 635 | self.action_transaction = QtWidgets.QAction(MainWindow) 636 | self.action_transaction.setCheckable(False) 637 | self.action_transaction.setObjectName("action_transaction") 638 | self.menu_more.addAction(self.action_transaction) 639 | self.menuBar.addAction(self.stu_menu.menuAction()) 640 | self.menuBar.addAction(self.teacher_menu.menuAction()) 641 | self.menuBar.addAction(self.sc_menu.menuAction()) 642 | self.menuBar.addAction(self.menu_more.menuAction()) 643 | self.menuBar.addAction(self.menu.menuAction()) 644 | 645 | self.retranslateUi(MainWindow) 646 | self.stu_delete.clicked.connect(MainWindow.stu_delete) 647 | self.stu_insert.clicked.connect(MainWindow.stu_insert) 648 | self.sc_insert.clicked.connect(MainWindow.sc_insert) 649 | self.sc_delete.clicked.connect(MainWindow.sc_delete) 650 | self.course_insert.clicked.connect(MainWindow.course_insert) 651 | self.course_delete.clicked.connect(MainWindow.course_delete) 652 | self.name_query.clicked.connect(MainWindow.get_name) 653 | self.name_query_by_cnum.clicked.connect(MainWindow.get_name_by_cnum) 654 | self.get_avg_grade.clicked.connect(MainWindow.get_avg_grade) 655 | self.create_view.clicked.connect(MainWindow.create_view) 656 | self.create_index.clicked.connect(MainWindow.create_index) 657 | self.action_transaction.triggered.connect(MainWindow.transaction_dialog) 658 | self.add_trigger.clicked.connect(MainWindow.change_combobox) 659 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 660 | MainWindow.setTabOrder(self.stu_num, self.stu_name) 661 | MainWindow.setTabOrder(self.stu_name, self.stu_insert) 662 | MainWindow.setTabOrder(self.stu_insert, self.stu_delete) 663 | MainWindow.setTabOrder(self.stu_delete, self.course_num) 664 | MainWindow.setTabOrder(self.course_num, self.course_name) 665 | MainWindow.setTabOrder(self.course_name, self.teacher_num) 666 | MainWindow.setTabOrder(self.teacher_num, self.course_insert) 667 | MainWindow.setTabOrder(self.course_insert, self.course_delete) 668 | MainWindow.setTabOrder(self.course_delete, self.sc_snum) 669 | MainWindow.setTabOrder(self.sc_snum, self.sc_cnum) 670 | MainWindow.setTabOrder(self.sc_cnum, self.sc_grade) 671 | MainWindow.setTabOrder(self.sc_grade, self.sc_insert) 672 | MainWindow.setTabOrder(self.sc_insert, self.sc_delete) 673 | 674 | def retranslateUi(self, MainWindow): 675 | _translate = QtCore.QCoreApplication.translate 676 | MainWindow.setWindowTitle(_translate("MainWindow", "教学管理系统@zjr")) 677 | self.label_23.setText(_translate("MainWindow", "修改表")) 678 | self.add_trigger.setText(_translate("MainWindow", "触发器:关")) 679 | self.label.setText(_translate("MainWindow", "插入与删除:学生表操作")) 680 | self.label_2.setText(_translate("MainWindow", "学号:")) 681 | self.label_3.setText(_translate("MainWindow", "姓名:")) 682 | self.label_11.setText(_translate("MainWindow", "班号:")) 683 | self.stu_insert.setText(_translate("MainWindow", "插入")) 684 | self.stu_delete.setText(_translate("MainWindow", "删除")) 685 | self.label_4.setText(_translate("MainWindow", "插入与删除:课程表操作")) 686 | self.label_5.setText(_translate("MainWindow", "课程号:")) 687 | self.label_6.setText(_translate("MainWindow", "课程名:")) 688 | self.label_12.setText(_translate("MainWindow", "教师号:")) 689 | self.course_insert.setText(_translate("MainWindow", "插入")) 690 | self.course_delete.setText(_translate("MainWindow", "删除")) 691 | self.label_9.setText(_translate("MainWindow", "插入与删除:选课表操作")) 692 | self.label_7.setText(_translate("MainWindow", "学号:")) 693 | self.label_8.setText(_translate("MainWindow", "课程号:")) 694 | self.label_10.setText(_translate("MainWindow", "成绩:")) 695 | self.sc_insert.setText(_translate("MainWindow", "插入")) 696 | self.sc_delete.setText(_translate("MainWindow", "删除")) 697 | self.label_24.setText(_translate("MainWindow", "查询表")) 698 | self.label_13.setText(_translate("MainWindow", "查询超过选课数目的学生名:\n" 699 | "选课表、学生表")) 700 | self.label_14.setText(_translate("MainWindow", "数目:")) 701 | self.name_query.setText(_translate("MainWindow", "查询")) 702 | self.label_15.setText(_translate("MainWindow", "查询选修该课程的学生姓名:\n" 703 | "选课表、学生表")) 704 | self.label_16.setText(_translate("MainWindow", "课程号:")) 705 | self.name_query_by_cnum.setText(_translate("MainWindow", "查询")) 706 | self.label_18.setText(_translate("MainWindow", "查询学生及格科目的平均成绩:\n" 707 | "选课表、学生表")) 708 | self.label_17.setText(_translate("MainWindow", "姓名:")) 709 | self.get_avg_grade.setText(_translate("MainWindow", "查询")) 710 | self.label_25.setText(_translate("MainWindow", "视图与索引")) 711 | self.label_20.setText(_translate("MainWindow", "为计算机学院的系建立视图")) 712 | self.label_19.setText(_translate("MainWindow", "院系:")) 713 | self.cs_department.setItemText(0, _translate("MainWindow", "计算机科学")) 714 | self.cs_department.setItemText(1, _translate("MainWindow", "信息安全")) 715 | self.cs_department.setItemText(2, _translate("MainWindow", "自然语言处理")) 716 | self.create_view.setText(_translate("MainWindow", "创建视图")) 717 | self.label_21.setText(_translate("MainWindow", "为学生非键属性建立索引")) 718 | self.label_22.setText(_translate("MainWindow", "属性:")) 719 | self.cs_index.setItemText(0, _translate("MainWindow", "name 姓名")) 720 | self.cs_index.setItemText(1, _translate("MainWindow", "age 年龄")) 721 | self.cs_index.setItemText(2, _translate("MainWindow", "gender 性别")) 722 | self.cs_index.setItemText(3, _translate("MainWindow", "c_num 班号")) 723 | self.create_index.setText(_translate("MainWindow", "创建索引")) 724 | self.stu_menu.setTitle(_translate("MainWindow", "学生表")) 725 | self.teacher_menu.setTitle(_translate("MainWindow", "教师表")) 726 | self.sc_menu.setTitle(_translate("MainWindow", "选课表")) 727 | self.menu_more.setTitle(_translate("MainWindow", "事务管理")) 728 | self.menu.setTitle(_translate("MainWindow", "关于")) 729 | self.action1.setText(_translate("MainWindow", "待开发")) 730 | self.action1_2.setText(_translate("MainWindow", "1")) 731 | self.action2.setText(_translate("MainWindow", "2")) 732 | self.action3.setText(_translate("MainWindow", "3")) 733 | self.stu_insert_act.setText(_translate("MainWindow", "插入")) 734 | self.stu_delete_act.setText(_translate("MainWindow", "删除")) 735 | self.action1_4.setText(_translate("MainWindow", "1")) 736 | self.action2_3.setText(_translate("MainWindow", "2")) 737 | self.action3_2.setText(_translate("MainWindow", "3")) 738 | self.action1_5.setText(_translate("MainWindow", "1")) 739 | self.action2_4.setText(_translate("MainWindow", "2")) 740 | self.stu_.setText(_translate("MainWindow", "3")) 741 | self.actiontodo.setText(_translate("MainWindow", "学生表")) 742 | self.action_transaction.setText(_translate("MainWindow", "开始转帐")) 743 | -------------------------------------------------------------------------------- /lab1/gui/transaction.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'transaction.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.14.1 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | 10 | from PyQt5 import QtCore, QtGui, QtWidgets 11 | 12 | 13 | class Ui_dialog(object): 14 | def setupUi(self, dialog): 15 | dialog.setObjectName("dialog") 16 | dialog.resize(527, 205) 17 | self.horizontalLayout = QtWidgets.QHBoxLayout(dialog) 18 | self.horizontalLayout.setObjectName("horizontalLayout") 19 | self.frame = QtWidgets.QFrame(dialog) 20 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 21 | sizePolicy.setHorizontalStretch(0) 22 | sizePolicy.setVerticalStretch(0) 23 | sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) 24 | self.frame.setSizePolicy(sizePolicy) 25 | self.frame.setFrameShape(QtWidgets.QFrame.Box) 26 | self.frame.setFrameShadow(QtWidgets.QFrame.Raised) 27 | self.frame.setObjectName("frame") 28 | self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) 29 | self.verticalLayout.setObjectName("verticalLayout") 30 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 31 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 32 | self.label = QtWidgets.QLabel(self.frame) 33 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 34 | sizePolicy.setHorizontalStretch(1) 35 | sizePolicy.setVerticalStretch(0) 36 | sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) 37 | self.label.setSizePolicy(sizePolicy) 38 | self.label.setObjectName("label") 39 | self.horizontalLayout_2.addWidget(self.label) 40 | self.sender_nums = QtWidgets.QComboBox(self.frame) 41 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 42 | sizePolicy.setHorizontalStretch(2) 43 | sizePolicy.setVerticalStretch(0) 44 | sizePolicy.setHeightForWidth(self.sender_nums.sizePolicy().hasHeightForWidth()) 45 | self.sender_nums.setSizePolicy(sizePolicy) 46 | self.sender_nums.setObjectName("sender_nums") 47 | self.horizontalLayout_2.addWidget(self.sender_nums) 48 | self.verticalLayout.addLayout(self.horizontalLayout_2) 49 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 50 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 51 | self.label_2 = QtWidgets.QLabel(self.frame) 52 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 53 | sizePolicy.setHorizontalStretch(1) 54 | sizePolicy.setVerticalStretch(0) 55 | sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) 56 | self.label_2.setSizePolicy(sizePolicy) 57 | self.label_2.setObjectName("label_2") 58 | self.horizontalLayout_3.addWidget(self.label_2) 59 | self.receivers_nums = QtWidgets.QComboBox(self.frame) 60 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 61 | sizePolicy.setHorizontalStretch(2) 62 | sizePolicy.setVerticalStretch(0) 63 | sizePolicy.setHeightForWidth(self.receivers_nums.sizePolicy().hasHeightForWidth()) 64 | self.receivers_nums.setSizePolicy(sizePolicy) 65 | self.receivers_nums.setObjectName("receivers_nums") 66 | self.horizontalLayout_3.addWidget(self.receivers_nums) 67 | self.verticalLayout.addLayout(self.horizontalLayout_3) 68 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 69 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 70 | self.add_exception = QtWidgets.QRadioButton(self.frame) 71 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 72 | sizePolicy.setHorizontalStretch(1) 73 | sizePolicy.setVerticalStretch(0) 74 | sizePolicy.setHeightForWidth(self.add_exception.sizePolicy().hasHeightForWidth()) 75 | self.add_exception.setSizePolicy(sizePolicy) 76 | self.add_exception.setObjectName("add_exception") 77 | self.horizontalLayout_4.addWidget(self.add_exception) 78 | self.transfer_num = QtWidgets.QSpinBox(self.frame) 79 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 80 | sizePolicy.setHorizontalStretch(1) 81 | sizePolicy.setVerticalStretch(0) 82 | sizePolicy.setHeightForWidth(self.transfer_num.sizePolicy().hasHeightForWidth()) 83 | self.transfer_num.setSizePolicy(sizePolicy) 84 | self.transfer_num.setObjectName("transfer_num") 85 | self.horizontalLayout_4.addWidget(self.transfer_num) 86 | self.verticalLayout.addLayout(self.horizontalLayout_4) 87 | self.begin_transfer = QtWidgets.QPushButton(self.frame) 88 | self.begin_transfer.setObjectName("begin_transfer") 89 | self.verticalLayout.addWidget(self.begin_transfer) 90 | self.horizontalLayout.addWidget(self.frame) 91 | self.stu_table = QtWidgets.QTableWidget(dialog) 92 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 93 | sizePolicy.setHorizontalStretch(0) 94 | sizePolicy.setVerticalStretch(0) 95 | sizePolicy.setHeightForWidth(self.stu_table.sizePolicy().hasHeightForWidth()) 96 | self.stu_table.setSizePolicy(sizePolicy) 97 | self.stu_table.setFrameShape(QtWidgets.QFrame.Box) 98 | self.stu_table.setObjectName("stu_table") 99 | self.stu_table.setColumnCount(0) 100 | self.stu_table.setRowCount(0) 101 | self.horizontalLayout.addWidget(self.stu_table) 102 | 103 | self.retranslateUi(dialog) 104 | self.begin_transfer.clicked.connect(dialog.begin_transaction) 105 | self.add_exception.clicked.connect(dialog.change_checkbox) 106 | QtCore.QMetaObject.connectSlotsByName(dialog) 107 | 108 | def retranslateUi(self, dialog): 109 | _translate = QtCore.QCoreApplication.translate 110 | dialog.setWindowTitle(_translate("dialog", "事务管理")) 111 | self.label.setText(_translate("dialog", "转账学号:")) 112 | self.label_2.setText(_translate("dialog", "收账学号:")) 113 | self.add_exception.setText(_translate("dialog", "模拟异常:关")) 114 | self.begin_transfer.setText(_translate("dialog", "开始转帐")) 115 | -------------------------------------------------------------------------------- /lab1/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QDialog, QTableWidgetItem, QHeaderView 4 | from lab1.gui import gui, transaction 5 | from PyQt5.QtGui import QIcon 6 | import pymysql 7 | import sys 8 | 9 | 10 | class MainWindow(QMainWindow): 11 | def __init__(self): 12 | super().__init__() 13 | self.setWindowIcon(QIcon('src/system.png')) 14 | 15 | def update_c_num_combobox(self): 16 | ui.c_num_combobox.clear() 17 | cur.execute('select num from course order by num asc') 18 | items = [item[0] for item in cur.fetchall()] 19 | ui.c_num_combobox.addItems(items) 20 | 21 | def update_s_name_combobox(self): 22 | ui.stu_name_combobox.clear() 23 | cur.execute('select num, name from student order by num asc') 24 | items = [item[0] + ' ' + item[1] for item in cur.fetchall()] 25 | ui.stu_name_combobox.addItems(items) 26 | 27 | def stu_insert(self): # 新建学生信息 28 | num, name, c_num = ui.stu_num.text(), ui.stu_name.text(), ui.class_num.text() 29 | if not num or not name or not c_num: 30 | QMessageBox.warning(self, '警告', '请输入学号、姓名与班号') 31 | elif not num.isdigit() or len(num) != 10 or not c_num.isdigit() or len(c_num) != 3: 32 | QMessageBox.warning(self, '警告', '学号为10位数字,班号为3位数字') 33 | else: 34 | query = 'select * from student where num=%s' 35 | if cur.execute(query, [num]): 36 | QMessageBox.warning(self, '插入异常', '该学号已存在,请重新输入') 37 | elif not cur.execute('select * from class where num=%s', [c_num]): 38 | QMessageBox.warning(self, '插入异常', '该班号在班级表中不存在,请尝试在班级表中插入对应条目') 39 | else: 40 | QMessageBox.information(self, '成功', '成功插入一条学生数据') 41 | query = 'insert into student(num,name,c_num) values (%s,%s,%s)' 42 | cur.execute(query, [num, name, c_num]) 43 | con.commit() # 修改数据时,需要commit操作 44 | self.update_s_name_combobox() 45 | 46 | def stu_delete(self): # 删除学生信息 47 | num, trigger_on = ui.stu_num.text(), ui.add_trigger.isChecked() 48 | if not num: 49 | QMessageBox.warning(self, '警告', '学号为空') 50 | elif not num.isdigit() or len(num) != 10: 51 | QMessageBox.warning(self, '警告', '学号只可为10位数字') 52 | else: 53 | query = 'select * from student where num=%s' 54 | if not cur.execute(query, [num]): 55 | QMessageBox.warning(self, "删除异常", "该学号不存在,请重新输入") 56 | elif cur.execute('select * from sc where snum =%s', [num]) and not trigger_on: 57 | QMessageBox.warning(self, "删除异常", "该学号正被选课表作为外键引用,请尝试删除对应条目") 58 | else: 59 | if cur.execute('select * from sc where snum=%s', [num]) and trigger_on: 60 | QMessageBox.information(self, '提示', '该学号正被选课表作为外键引用,触发器已默认删除对应条目数据') 61 | QMessageBox.information(self, '成功', '成功删除一条学生数据') 62 | query = 'delete from student where num=%s' 63 | cur.execute(query, [num]) 64 | con.commit() # 修改数据时,需要commit操作 65 | self.update_s_name_combobox() 66 | 67 | def course_insert(self): # 新建学生信息 68 | num, name, t_num = ui.course_num.text(), ui.course_name.text(), ui.teacher_num.text() 69 | if not num or not name or not t_num: 70 | QMessageBox.warning(self, '警告', '请输入课程号、课程名和任课教师号') 71 | elif not num.isdigit() or len(num) != 3 or not num.isdigit() or len(t_num) != 10: 72 | QMessageBox.warning(self, '警告', '课程号为3位数字,教师号为10位数字') 73 | else: 74 | query = 'select * from course where num=%s' 75 | if cur.execute(query, [num]): 76 | QMessageBox.warning(self, '插入异常', '该课程号已存在,请重新输入') 77 | elif not cur.execute('select * from teacher where num=%s', [t_num]): 78 | QMessageBox.warning(self, '插入异常', '该教师号在教师表中不存在,请尝试在教师表中插入对应条目') 79 | else: 80 | QMessageBox.information(self, '成功', '成功插入一条课程数据') 81 | query = 'insert into course(num,name,t_num) values (%s,%s,%s)' 82 | cur.execute(query, [num, name, t_num]) 83 | con.commit() # 修改数据时,需要commit操作 84 | self.update_c_num_combobox() 85 | 86 | def course_delete(self): # 删除学生信息 87 | num, trigger_on = ui.course_num.text(), ui.add_trigger.isChecked() 88 | if not num: 89 | QMessageBox.warning(self, '警告', '课程号为空') 90 | elif not num.isdigit() or len(num) != 3: 91 | QMessageBox.warning(self, '警告', '课程号只可为3位数字') 92 | else: 93 | query = 'select * from course where num=%s' 94 | if not cur.execute(query, [num]): 95 | QMessageBox.warning(self, "删除异常", "该课程号不存在,请重新输入") 96 | elif cur.execute('select * from sc where cnum=%s', [num]) and not trigger_on: 97 | QMessageBox.warning(self, "删除异常", "该课程号正被选课表作为外键引用,请尝试删除对应条目") 98 | else: 99 | if cur.execute('select * from sc where cnum=%s', [num]) and trigger_on: 100 | QMessageBox.information(self, '提示', '该课程号正被选课表作为外键引用,触发器已默认删除对应条目数据') 101 | QMessageBox.information(self, '成功', '成功删除一条课程数据') 102 | query = 'delete from course where num=%s' 103 | cur.execute(query, [num]) 104 | con.commit() # 修改数据时,需要commit操作 105 | self.update_c_num_combobox() 106 | 107 | def sc_insert(self): # 新建信息,加入触发器 108 | s_num, c_num, grade = ui.sc_snum.text(), ui.sc_cnum.text(), ui.sc_grade.text() 109 | if not s_num or not c_num: 110 | QMessageBox.warning(self, '警告', '请输入学号课程号') 111 | elif not s_num.isdigit() or len(s_num) != 10 or not c_num.isdigit() or len(c_num) != 3: 112 | QMessageBox.warning(self, '警告', '学号为10为数字,课程号为3位数字') 113 | else: 114 | query = 'select * from sc where snum=%s and cnum=%s' 115 | trigger_on = ui.add_trigger.isChecked() # 触发器是否打开 116 | has_s_num, has_c_num = cur.execute('select * from student where num=%s', [s_num]), cur.execute( 117 | 'select * from course where num=%s', [c_num]) # 学号信息是否存在,班号信息是否存在 118 | if cur.execute(query, [s_num, c_num]): 119 | QMessageBox.warning(self, '插入异常', '该选课信息已存在,请重新输入') 120 | elif not has_s_num and not trigger_on: 121 | QMessageBox.warning(self, '插入异常', '该学号在学生表中不存在,请尝试在学生表中插入对应条目') 122 | elif not has_c_num and not trigger_on: 123 | QMessageBox.warning(self, '插入异常', '该课程号在课程表中不存在,请尝试在课程表中插入对应条目') 124 | else: 125 | if not has_s_num and trigger_on: 126 | QMessageBox.information(self, '提示', '该学号在课程表中不存在,触发器已默认添加对应条目数据') 127 | if not has_c_num and trigger_on: 128 | QMessageBox.information(self, '提示', '该课程号在课程表中不存在,触发器已默认添加对应条目数据') 129 | QMessageBox.information(self, '成功', '成功插入一条学生数据') 130 | query = 'insert into sc(snum,cnum,grade) values (%s,%s,%s)' 131 | cur.execute(query, [s_num, c_num, grade]) 132 | con.commit() # 修改数据时,需要commit操作 133 | self.update_s_name_combobox() 134 | self.update_c_num_combobox() 135 | 136 | def sc_delete(self): # 删除信息,加入触发器 137 | s_num, c_num = ui.sc_snum.text(), ui.sc_cnum.text() 138 | if not s_num or not c_num: 139 | QMessageBox.warning(self, '警告', '请输入学号课程号') 140 | elif not s_num.isdigit() or len(s_num) != 10 or not c_num.isdigit() or len(c_num) != 3: 141 | QMessageBox.warning(self, '警告', '学号为10为数字,课程号为3位数字') 142 | else: 143 | query = 'select * from sc where snum=%s and cnum=%s' 144 | if not cur.execute(query, [s_num, c_num]): 145 | QMessageBox.warning(self, "删除异常", "该选课信息不存在,请重新输入") 146 | else: 147 | QMessageBox.information(self, '成功', '成功删除一条选课信息') 148 | query = 'delete from sc where snum=%s and cnum=%s' 149 | cur.execute(query, [s_num, c_num]) 150 | con.commit() # 修改数据时,需要commit操作 151 | self.update_s_name_combobox() 152 | self.update_c_num_combobox() 153 | 154 | def get_name(self): 155 | c_count, res = int(ui.sc_stu_count.text()), [] 156 | query = 'select student.name from student,sc where student.num = sc.snum group by student.num HAVING count(*) > %s' 157 | cur.execute(query, [c_count]) 158 | for item in cur.fetchall(): 159 | res.append(item[0]) 160 | QMessageBox.information(self, '成功', ' '.join(res) if len(res) > 0 else '无结果') 161 | 162 | def get_name_by_cnum(self): 163 | c_num, res = ui.c_num_combobox.currentText(), [] 164 | if not c_num: 165 | QMessageBox.warning(self, '警告', '请输入课程号') 166 | elif not c_num.isdigit() or len(c_num) != 3: 167 | QMessageBox.warning(self, '警告', '班号为3位数字') 168 | else: 169 | query = 'select name from student where num in (select snum from sc where cnum = %s)' 170 | cur.execute(query, [c_num]) 171 | for item in cur.fetchall(): 172 | res.append(item[0]) 173 | QMessageBox.information(self, '成功', ' '.join(res) if len(res) > 0 else '无结果') 174 | 175 | def get_avg_grade(self): 176 | name, res = ui.stu_name_combobox.currentText().split()[1], [] 177 | if not name: 178 | QMessageBox.warning(self, '警告', '请输入姓名') 179 | else: 180 | query = 'select snum, avg(grade) from sc where snum in (select num from student where name = %s) and grade >= 60 group by snum' 181 | cur.execute(query, [name]) 182 | for item in cur.fetchall(): 183 | res.append(item[0] + '\t' + str(item[1])) 184 | QMessageBox.information(self, '成功', '\n'.join(res) if len(res) != 0 else '无结果') 185 | 186 | def create_view(self): 187 | d_name = ui.cs_department.currentText() 188 | view_name = 'cs_student' + str(ui.cs_department.currentIndex()) 189 | query = 'select count(*) from information_schema.VIEWS where TABLE_SCHEMA="teaching_management_system" and TABLE_NAME=%s' 190 | cur.execute(query, [view_name]) # 先查询视图是否已被定义 191 | if cur.fetchone()[0] == 1: 192 | QMessageBox.warning(self, '警告', '视图已被定义:' + view_name) 193 | else: 194 | query = 'create view ' + view_name + ' as select num,name,c_num from student where c_num in (select c_num from class where d_num in (select d_num from department where c_num="001" and name=%s))' 195 | cur.execute(query, [d_name]) 196 | QMessageBox.information(self, '成功', '成功创建视图:' + view_name) 197 | 198 | def create_index(self): 199 | index = ui.cs_index.currentText().split()[0] 200 | query = 'select count(*) from information_schema.INNODB_INDEXES where NAME=%s' 201 | cur.execute(query, [index + '_index']) # 先查询视图是否已被定义 202 | if cur.fetchone()[0] == 1: 203 | QMessageBox.warning(self, '警告', '索引已被定义:' + index) 204 | else: 205 | query = 'create index ' + index + '_index on student(' + index + ' desc) ' 206 | cur.execute(query) 207 | QMessageBox.information(self, '成功', '成功创建索引:' + index + '_index') 208 | 209 | def transaction_dialog(self): 210 | dialog = TransactionDialog(self) 211 | dialog_ui = transaction.Ui_dialog() 212 | dialog_ui.setupUi(dialog) 213 | dialog.set_ui(dialog_ui) 214 | dialog.show() 215 | 216 | def change_combobox(self): 217 | ui.add_trigger.setText('触发器:' + ('开' if ui.add_trigger.isChecked() else '关')) 218 | 219 | 220 | class TransactionDialog(QDialog): 221 | 222 | def set_ui(self, ui): 223 | self.ui = ui 224 | self.__update_num() 225 | 226 | def __update_num(self): 227 | cur.execute('select num,name,balance from student order by num asc') 228 | items = cur.fetchall() 229 | res = [item[0] + ' ' + str(item[2]) for item in items] 230 | self.ui.sender_nums.clear() 231 | self.ui.receivers_nums.clear() 232 | self.ui.sender_nums.addItems(res) 233 | self.ui.receivers_nums.addItems(res) 234 | table = self.ui.stu_table 235 | table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) 236 | table.setRowCount(len(items)) 237 | table.setColumnCount(3) 238 | table.verticalHeader().setVisible(False) 239 | table.setHorizontalHeaderLabels(['学号', '姓名', '余额']) 240 | for idx, item in enumerate(items): 241 | table.setItem(idx, 0, QTableWidgetItem(item[0])) 242 | table.setItem(idx, 1, QTableWidgetItem(item[1])) 243 | table.setItem(idx, 2, QTableWidgetItem(str(item[2]))) 244 | 245 | def begin_transaction(self): 246 | is_checked = self.ui.add_exception.isChecked() 247 | con.begin() # 开启事务 248 | try: 249 | sender, s_balance = self.ui.sender_nums.currentText().split() 250 | receiver, r_balance = self.ui.receivers_nums.currentText().split() 251 | transfer_num = self.ui.transfer_num.text() 252 | if sender == receiver or int(s_balance) < int(transfer_num) or is_checked: 253 | raise Exception 254 | else: 255 | QMessageBox.information(self, '提示', '正在转帐') 256 | cur.execute('update student set balance=balance-' + (transfer_num) + ' where num = %s', sender) 257 | cur.execute('update student set balance=balance+' + transfer_num + ' where num = %s', receiver) 258 | except Exception as e: 259 | QMessageBox.warning(self, '警告', '数据库接收到错误,开始回退,转账失败') 260 | con.rollback() 261 | else: 262 | con.commit() 263 | QMessageBox.information(self, '提示', '转账成功') 264 | self.__update_num() 265 | 266 | def change_checkbox(self): 267 | self.ui.add_exception.setText('模拟异常:' + ('开' if self.ui.add_exception.isChecked() else '关')) 268 | 269 | 270 | if __name__ == "__main__": 271 | con = pymysql.connect(host='localhost', port=3306, user='root', password='123456', charset='utf8', 272 | database='teaching_management_system') # 连接数据库 273 | cur = con.cursor() # 执行sql语句的游标 274 | 275 | app = QApplication(sys.argv) 276 | 277 | main_win = MainWindow() 278 | ui = gui.Ui_MainWindow() 279 | ui.setupUi(main_win) 280 | main_win.update_c_num_combobox() 281 | main_win.update_s_name_combobox() 282 | 283 | main_win.show() 284 | sys.exit(app.exec_()) 285 | -------------------------------------------------------------------------------- /lab1/src/ER图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/ER图.jpg -------------------------------------------------------------------------------- /lab1/src/Pycharm生成的系统图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/Pycharm生成的系统图.png -------------------------------------------------------------------------------- /lab1/src/system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/system.png -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_class.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `class` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `class`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `class` ( 26 | `num` varchar(3) NOT NULL, 27 | `d_num` varchar(3) DEFAULT NULL, 28 | PRIMARY KEY (`num`), 29 | KEY `class_fk_department` (`d_num`), 30 | CONSTRAINT `class_fk_department` FOREIGN KEY (`d_num`) REFERENCES `department` (`num`) 31 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 32 | /*!40101 SET character_set_client = @saved_cs_client */; 33 | 34 | -- 35 | -- Dumping data for table `class` 36 | -- 37 | 38 | LOCK TABLES `class` WRITE; 39 | /*!40000 ALTER TABLE `class` DISABLE KEYS */; 40 | INSERT INTO `class` VALUES ('001','001'),('002','001'),('003','002'); 41 | /*!40000 ALTER TABLE `class` ENABLE KEYS */; 42 | UNLOCK TABLES; 43 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 44 | 45 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 46 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 47 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 48 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 49 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 50 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 51 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 52 | 53 | -- Dump completed on 2020-04-10 13:51:57 54 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_college.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `college` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `college`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `college` ( 26 | `num` varchar(3) NOT NULL, 27 | `name` varchar(10) NOT NULL, 28 | PRIMARY KEY (`num`) 29 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 30 | /*!40101 SET character_set_client = @saved_cs_client */; 31 | 32 | -- 33 | -- Dumping data for table `college` 34 | -- 35 | 36 | LOCK TABLES `college` WRITE; 37 | /*!40000 ALTER TABLE `college` DISABLE KEYS */; 38 | INSERT INTO `college` VALUES ('001','计算机学院'),('002','数学学院'),('003','外国语学院'); 39 | /*!40000 ALTER TABLE `college` ENABLE KEYS */; 40 | UNLOCK TABLES; 41 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 42 | 43 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 44 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 45 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 46 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 47 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 48 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 49 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 50 | 51 | -- Dump completed on 2020-04-10 13:51:57 52 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_course.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `course` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `course`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `course` ( 26 | `num` varchar(3) NOT NULL, 27 | `name` varchar(15) NOT NULL, 28 | `t_num` varchar(10) NOT NULL DEFAULT '0172510217', 29 | PRIMARY KEY (`num`), 30 | KEY `course_fk_teacher` (`t_num`), 31 | CONSTRAINT `course_fk_teacher` FOREIGN KEY (`t_num`) REFERENCES `teacher` (`num`) 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 33 | /*!40101 SET character_set_client = @saved_cs_client */; 34 | 35 | -- 36 | -- Dumping data for table `course` 37 | -- 38 | 39 | LOCK TABLES `course` WRITE; 40 | /*!40000 ALTER TABLE `course` DISABLE KEYS */; 41 | INSERT INTO `course` VALUES ('001','数据库系统','0172510217'),('002','计算机体系结构','0172510217'),('003','自然语言处理','0172510218'),('004','数学','0172510217'),('005','数学','0172510219'),('010','数学','0172510218'); 42 | /*!40000 ALTER TABLE `course` ENABLE KEYS */; 43 | UNLOCK TABLES; 44 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 45 | 46 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 47 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 48 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 49 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 50 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 51 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 52 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 53 | 54 | -- Dump completed on 2020-04-10 13:51:57 55 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_department.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `department` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `department`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `department` ( 26 | `num` varchar(3) NOT NULL, 27 | `name` varchar(15) NOT NULL, 28 | `c_num` varchar(3) NOT NULL, 29 | PRIMARY KEY (`num`), 30 | KEY `department_fk_college` (`c_num`), 31 | CONSTRAINT `department_fk_college` FOREIGN KEY (`c_num`) REFERENCES `college` (`num`) 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 33 | /*!40101 SET character_set_client = @saved_cs_client */; 34 | 35 | -- 36 | -- Dumping data for table `department` 37 | -- 38 | 39 | LOCK TABLES `department` WRITE; 40 | /*!40000 ALTER TABLE `department` DISABLE KEYS */; 41 | INSERT INTO `department` VALUES ('001','计算机科学','001'),('002','信息安全','001'),('003','自然语言处理','001'),('004','数学基础','002'),('005','数学应用','002'),('006','俄语','003'); 42 | /*!40000 ALTER TABLE `department` ENABLE KEYS */; 43 | UNLOCK TABLES; 44 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 45 | 46 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 47 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 48 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 49 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 50 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 51 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 52 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 53 | 54 | -- Dump completed on 2020-04-10 13:51:57 55 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_dorm.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `dorm` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `dorm`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `dorm` ( 26 | `num` varchar(3) NOT NULL, 27 | `c_num` varchar(3) NOT NULL, 28 | PRIMARY KEY (`num`), 29 | KEY `c_num` (`c_num`), 30 | CONSTRAINT `dorm_ibfk_1` FOREIGN KEY (`c_num`) REFERENCES `college` (`num`) 31 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 32 | /*!40101 SET character_set_client = @saved_cs_client */; 33 | 34 | -- 35 | -- Dumping data for table `dorm` 36 | -- 37 | 38 | LOCK TABLES `dorm` WRITE; 39 | /*!40000 ALTER TABLE `dorm` DISABLE KEYS */; 40 | INSERT INTO `dorm` VALUES ('001','001'),('002','001'),('003','002'); 41 | /*!40000 ALTER TABLE `dorm` ENABLE KEYS */; 42 | UNLOCK TABLES; 43 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 44 | 45 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 46 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 47 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 48 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 49 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 50 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 51 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 52 | 53 | -- Dump completed on 2020-04-10 13:51:57 54 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_laboratory.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `laboratory` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `laboratory`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `laboratory` ( 26 | `num` varchar(3) NOT NULL, 27 | `name` varchar(10) NOT NULL, 28 | `c_num` varchar(3) NOT NULL, 29 | PRIMARY KEY (`num`), 30 | KEY `laboratory_fk_college` (`c_num`), 31 | CONSTRAINT `laboratory_fk_college` FOREIGN KEY (`c_num`) REFERENCES `college` (`num`) 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 33 | /*!40101 SET character_set_client = @saved_cs_client */; 34 | 35 | -- 36 | -- Dumping data for table `laboratory` 37 | -- 38 | 39 | LOCK TABLES `laboratory` WRITE; 40 | /*!40000 ALTER TABLE `laboratory` DISABLE KEYS */; 41 | INSERT INTO `laboratory` VALUES ('001','量子计算','001'),('002','生物信息','001'); 42 | /*!40000 ALTER TABLE `laboratory` ENABLE KEYS */; 43 | UNLOCK TABLES; 44 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 45 | 46 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 47 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 48 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 49 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 50 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 51 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 52 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 53 | 54 | -- Dump completed on 2020-04-10 13:51:57 55 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_sc.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `sc` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `sc`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `sc` ( 26 | `cnum` varchar(3) NOT NULL, 27 | `snum` varchar(10) NOT NULL, 28 | `grade` varchar(3) DEFAULT '60', 29 | PRIMARY KEY (`cnum`,`snum`), 30 | KEY `grade_fk_snum` (`snum`), 31 | CONSTRAINT `grade_fk_cnum` FOREIGN KEY (`cnum`) REFERENCES `course` (`num`), 32 | CONSTRAINT `grade_fk_snum` FOREIGN KEY (`snum`) REFERENCES `student` (`num`) 33 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 34 | /*!40101 SET character_set_client = @saved_cs_client */; 35 | 36 | -- 37 | -- Dumping data for table `sc` 38 | -- 39 | 40 | LOCK TABLES `sc` WRITE; 41 | /*!40000 ALTER TABLE `sc` DISABLE KEYS */; 42 | INSERT INTO `sc` VALUES ('001','1172510218','100'),('001','1172510219','60'),('002','1172510218','80'),('003','1172510219','40'); 43 | /*!40000 ALTER TABLE `sc` ENABLE KEYS */; 44 | UNLOCK TABLES; 45 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 46 | 47 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 48 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 49 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 50 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 51 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 52 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 53 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 54 | 55 | -- Dump completed on 2020-04-10 13:51:57 56 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_student.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `student` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `student`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `student` ( 26 | `num` varchar(10) NOT NULL, 27 | `name` varchar(10) NOT NULL, 28 | `c_num` varchar(3) NOT NULL DEFAULT '001', 29 | `age` varchar(3) DEFAULT '20', 30 | `gender` varchar(3) DEFAULT '男', 31 | `balance` int DEFAULT '100', 32 | PRIMARY KEY (`num`), 33 | KEY `stu2class` (`c_num`), 34 | KEY `name_index` (`name` DESC), 35 | CONSTRAINT `stu2class` FOREIGN KEY (`c_num`) REFERENCES `class` (`num`) 36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 37 | /*!40101 SET character_set_client = @saved_cs_client */; 38 | 39 | -- 40 | -- Dumping data for table `student` 41 | -- 42 | 43 | LOCK TABLES `student` WRITE; 44 | /*!40000 ALTER TABLE `student` DISABLE KEYS */; 45 | INSERT INTO `student` VALUES ('1172510218','张明','002','19','男',50),('1172510219','张量','001','21','男',200),('1172510220','1172510220','001','20','男',100),('1172510225','张宁','001','20','男',100); 46 | /*!40000 ALTER TABLE `student` ENABLE KEYS */; 47 | UNLOCK TABLES; 48 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 49 | 50 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 51 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 52 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 53 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 54 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 55 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 56 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 57 | 58 | -- Dump completed on 2020-04-10 13:51:57 59 | -------------------------------------------------------------------------------- /lab1/src/teaching_management_system_teacher.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: teaching_management_system 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.19 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `teacher` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `teacher`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `teacher` ( 26 | `num` varchar(10) NOT NULL, 27 | `name` varchar(10) NOT NULL, 28 | `d_num` varchar(3) NOT NULL, 29 | PRIMARY KEY (`num`), 30 | KEY `d_num` (`d_num`), 31 | CONSTRAINT `teacher_ibfk_1` FOREIGN KEY (`d_num`) REFERENCES `department` (`num`) 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 33 | /*!40101 SET character_set_client = @saved_cs_client */; 34 | 35 | -- 36 | -- Dumping data for table `teacher` 37 | -- 38 | 39 | LOCK TABLES `teacher` WRITE; 40 | /*!40000 ALTER TABLE `teacher` DISABLE KEYS */; 41 | INSERT INTO `teacher` VALUES ('0172510217','张良','001'),('0172510218','李明','001'),('0172510219','王虎','002'); 42 | /*!40000 ALTER TABLE `teacher` ENABLE KEYS */; 43 | UNLOCK TABLES; 44 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 45 | 46 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 47 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 48 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 49 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 50 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 51 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 52 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 53 | 54 | -- Dump completed on 2020-04-10 13:51:57 55 | -------------------------------------------------------------------------------- /lab1/src/主界面运行截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/主界面运行截图.png -------------------------------------------------------------------------------- /lab1/src/事务管理主要流程图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/事务管理主要流程图.jpg -------------------------------------------------------------------------------- /lab1/src/事务管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/事务管理界面.png -------------------------------------------------------------------------------- /lab1/src/删除学生信息主要流程图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/删除学生信息主要流程图.jpg -------------------------------------------------------------------------------- /lab1/src/查询优化GUI展示.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/查询优化GUI展示.png -------------------------------------------------------------------------------- /lab1/src/磁盘操作截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/磁盘操作截图.png -------------------------------------------------------------------------------- /lab1/src/视图创建界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HIT-SCIR-chichi/hit_db_lab/4b63074f48131fd0bb5b11bcbb84e3cb27729a4a/lab1/src/视图创建界面.png -------------------------------------------------------------------------------- /lab2/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ -------------------------------------------------------------------------------- /lab2/README.md: -------------------------------------------------------------------------------- 1 | # 实验二:存储管理与查询优化算法的设计 2 | ## 还有哪些不足 3 | - 磁盘操作中需要做的部分以**todo**标识 4 | - 查询优化操作中未实现**投影操作**的优化 5 | ## 准备部分 6 | - 根据原extmem.c程序的设计思想写出类似的python代码extmem.py 7 | - 生成关系R和S的数据:extmem.gene_data() 8 | - 将数据写入到模拟磁盘中:extmem.write_disk() 9 | ## 存储管理 10 | - 关系选择 11 | - 线性选择,顺序遍历所有的关系磁盘块 12 | - 将缓冲区的1块作为关系数据输入块,1块作为输出块 13 | - 磁盘IO为`B(r)+B(t)` 14 | - 关系投影 15 | - 需要去重,顺序遍历所有的关系磁盘块 16 | - 将缓冲区的1块作为关系数据输入块,B(buffer)-1块作为输出块 17 | - 结果需要排序去重(外排序) 18 | - nested-loop-join 19 | - 关系R做外层循环内容,S做内层循环内容 20 | - 缓冲区的B(buffer)-2块作为R数据输入块,1块做S数据输入块,1块作为输出块 21 | - 磁盘IO为`B(r)+B(r)*B(s)/(B(buffer)-2)+B(t)` 22 | - sort-merge-join:由于(B(buffer)-1)^2 int: 19 | for idx, flag in enumerate(self.data_occupy): 20 | if not flag: 21 | self.data_occupy[idx] = True 22 | self.free_blk_num -= 1 23 | return idx 24 | return -1 25 | 26 | def free_blk(self, index) -> bool: # 释放缓冲区的一个磁盘块 27 | flag = self.data_occupy[index] 28 | if flag: 29 | self.free_blk_num += 1 30 | self.data_occupy[index] = False 31 | return flag 32 | 33 | def load_blk(self, addr: str) -> int: # 加载磁盘块到缓冲区中,输入参数形如'./disk/relation/r15.blk' 34 | index = self.get_free_blk() 35 | if index != -1: 36 | with open(addr) as f: 37 | self.data_occupy[index] = True 38 | self.data[index] = f.read().split('\n') 39 | self.io_num += 1 40 | return index 41 | 42 | def write_blk(self, addr, index): # 将缓冲区中数据写入磁盘块 43 | with open(addr, 'w') as f: 44 | self.io_num += 1 45 | self.free_blk_num += 1 46 | self.data_occupy[index] = False 47 | f.write('\n'.join(self.data[index])) 48 | return True 49 | 50 | def write_buffer(self, data_lst: list, addr): # 将CPU处理后的数据暂存入缓冲区,再存入磁盘 51 | index = self.get_free_blk() 52 | if index != -1: 53 | self.data[index] = data_lst 54 | self.write_blk(addr, index) 55 | return index != -1 56 | 57 | 58 | def drop_blk(addr: str) -> bool: # 存在返回真,不存在返回假 59 | blk_path = disk_dir + addr + '.blk' 60 | blk_exists = os.path.exists(blk_path) 61 | if blk_exists: 62 | os.remove(blk_path) 63 | return blk_exists 64 | 65 | 66 | def drop_blk_in_dir(file_dir: str): 67 | for file in os.listdir(file_dir): 68 | os.remove(file_dir + file) 69 | 70 | 71 | def gene_data(): 72 | drop_blk_in_dir(disk_dir) 73 | all_data, item = [([], set(), blk_num1 * tuple_num, 1, 40), ([], set(), blk_num2 * tuple_num, 20, 60)], None 74 | for data in all_data: 75 | for idx in range(data[2]): # data[2]保存的是关系元组数目 76 | while True: 77 | item = (randint(data[3], data[4]), randint(1, 1000)) # data[3]和data[4]保存属性A和C的值域上下界 78 | if item not in data[1]: # data[1]是一个集合,用于生成唯一的元组 79 | break 80 | data[0].append(item) # data[0]用于保存最终结果 81 | data[1].add(item) 82 | return all_data[0][0], all_data[1][0] 83 | 84 | 85 | def write_disk(r_lst: list, s_lst: list): 86 | all_data = [('r', blk_num1, r_lst), ('s', blk_num2, s_lst)] 87 | for data in all_data: # 将关系实例写入模拟磁盘 88 | for idx in range(data[1]): 89 | with open('%s%s%d.blk' % (disk_dir, data[0], idx), 'w') as f: 90 | blk_data = ['%d %d' % item for item in data[2][idx * tuple_num:(idx + 1) * tuple_num]] 91 | f.write('\n'.join(blk_data)) 92 | 93 | 94 | if __name__ == '__main__': 95 | r, s = gene_data() # 生成关系R和S的随机数据 96 | write_disk(r, s) # 将数据写入模拟磁盘 97 | -------------------------------------------------------------------------------- /lab2/gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'gui.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.14.1 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | 10 | from PyQt5 import QtCore, QtGui, QtWidgets 11 | 12 | 13 | class Ui_MainWindow(object): 14 | def setupUi(self, MainWindow): 15 | MainWindow.setObjectName("MainWindow") 16 | MainWindow.resize(660, 464) 17 | icon = QtGui.QIcon() 18 | icon.addPixmap(QtGui.QPixmap("../lab1/src/system.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 19 | MainWindow.setWindowIcon(icon) 20 | self.centralwidget = QtWidgets.QWidget(MainWindow) 21 | self.centralwidget.setObjectName("centralwidget") 22 | self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) 23 | self.verticalLayout.setObjectName("verticalLayout") 24 | self.query_table = QtWidgets.QTableWidget(self.centralwidget) 25 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 26 | sizePolicy.setHorizontalStretch(0) 27 | sizePolicy.setVerticalStretch(0) 28 | sizePolicy.setHeightForWidth(self.query_table.sizePolicy().hasHeightForWidth()) 29 | self.query_table.setSizePolicy(sizePolicy) 30 | self.query_table.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) 31 | self.query_table.setColumnCount(2) 32 | self.query_table.setObjectName("query_table") 33 | self.query_table.setRowCount(0) 34 | self.query_table.horizontalHeader().setVisible(False) 35 | self.query_table.verticalHeader().setVisible(False) 36 | self.verticalLayout.addWidget(self.query_table) 37 | self.frame = QtWidgets.QFrame(self.centralwidget) 38 | self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) 39 | self.frame.setFrameShadow(QtWidgets.QFrame.Raised) 40 | self.frame.setObjectName("frame") 41 | self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) 42 | self.horizontalLayout.setObjectName("horizontalLayout") 43 | self.optimize_on = QtWidgets.QRadioButton(self.frame) 44 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 45 | sizePolicy.setHorizontalStretch(1) 46 | sizePolicy.setVerticalStretch(0) 47 | sizePolicy.setHeightForWidth(self.optimize_on.sizePolicy().hasHeightForWidth()) 48 | self.optimize_on.setSizePolicy(sizePolicy) 49 | self.optimize_on.setObjectName("optimize_on") 50 | self.horizontalLayout.addWidget(self.optimize_on) 51 | self.query_box = QtWidgets.QComboBox(self.frame) 52 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) 53 | sizePolicy.setHorizontalStretch(2) 54 | sizePolicy.setVerticalStretch(0) 55 | sizePolicy.setHeightForWidth(self.query_box.sizePolicy().hasHeightForWidth()) 56 | self.query_box.setSizePolicy(sizePolicy) 57 | self.query_box.setObjectName("query_box") 58 | self.horizontalLayout.addWidget(self.query_box) 59 | self.parse_button = QtWidgets.QPushButton(self.frame) 60 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 61 | sizePolicy.setHorizontalStretch(2) 62 | sizePolicy.setVerticalStretch(0) 63 | sizePolicy.setHeightForWidth(self.parse_button.sizePolicy().hasHeightForWidth()) 64 | self.parse_button.setSizePolicy(sizePolicy) 65 | self.parse_button.setObjectName("parse_button") 66 | self.horizontalLayout.addWidget(self.parse_button) 67 | self.verticalLayout.addWidget(self.frame) 68 | self.parse_tree = QtWidgets.QTreeWidget(self.centralwidget) 69 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 70 | sizePolicy.setHorizontalStretch(0) 71 | sizePolicy.setVerticalStretch(1) 72 | sizePolicy.setHeightForWidth(self.parse_tree.sizePolicy().hasHeightForWidth()) 73 | self.parse_tree.setSizePolicy(sizePolicy) 74 | self.parse_tree.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) 75 | self.parse_tree.setObjectName("parse_tree") 76 | self.verticalLayout.addWidget(self.parse_tree) 77 | MainWindow.setCentralWidget(self.centralwidget) 78 | 79 | self.retranslateUi(MainWindow) 80 | self.parse_button.clicked.connect(MainWindow.query) 81 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 82 | 83 | def retranslateUi(self, MainWindow): 84 | _translate = QtCore.QCoreApplication.translate 85 | MainWindow.setWindowTitle(_translate("MainWindow", "语法树")) 86 | self.optimize_on.setText(_translate("MainWindow", "优化开启")) 87 | self.parse_button.setText(_translate("MainWindow", "查询")) 88 | -------------------------------------------------------------------------------- /lab2/query_optimize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | 查询优化算法的设计与实现. 5 | """ 6 | from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QHeaderView, QTreeWidgetItem, QStyleFactory 7 | from lab2.gui import Ui_MainWindow 8 | import sys 9 | 10 | query0 = 'SELECT [ ENAME = ’Mary’ & DNAME = ’Research’ ] ( EMPLOYEE JOIN DEPARTMENT )' 11 | query1 = 'SELECT [ ESSN = ’01’ ] ( PROJECTION [ ESSN, PNAME ] ( WORKS_ON JOIN PROJECT ) )' 12 | query2 = 'PROJECTION [ BDATE ] ( SELECT [ ENAME = ’John’ & DNAME = ’ Research’ ] ( EMPLOYEE JOIN DEPARTMENT ) )' 13 | queries = [query0, query1, query2] 14 | 15 | 16 | class TreeNode: 17 | def __init__(self, op='', info=''): 18 | self.child = [] # 儿子节点 19 | self.op = op 20 | self.info = info 21 | 22 | def __str__(self): 23 | return (self.op if self.op else '') + (' ' + self.info if self.info else '') 24 | 25 | 26 | class MainWindow(QMainWindow): 27 | def __init__(self, ui_main_win: Ui_MainWindow): 28 | super().__init__() 29 | self.ui = ui_main_win 30 | ui_main_win.setupUi(self) 31 | self.set_query() 32 | 33 | def set_query(self): 34 | self.ui.query_table.setRowCount(len(queries)) 35 | self.ui.query_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents) 36 | self.ui.query_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) 37 | for idx, query in enumerate(queries): 38 | self.ui.query_table.setItem(idx, 0, QTableWidgetItem('query%d' % idx)) 39 | self.ui.query_table.setItem(idx, 1, QTableWidgetItem(query)) 40 | self.ui.query_box.addItems(['query%d' % idx for idx in range(len(queries))]) 41 | 42 | def query(self): 43 | root = get_tree(queries[self.ui.query_box.currentIndex()]) 44 | if self.ui.optimize_on.isChecked(): 45 | root = optimize(root) 46 | # output_tree(root) 47 | tree_stack, item_stack = [root], [QTreeWidgetItem(self.ui.parse_tree)] 48 | while tree_stack: 49 | tree_node, item_node = tree_stack.pop(0), item_stack.pop(0) 50 | item_node.setText(0, str(tree_node)) 51 | tree_stack = tree_node.child + tree_stack 52 | item_stack = [QTreeWidgetItem(item_node) for child in tree_node.child] + item_stack 53 | self.ui.parse_tree.expandAll() 54 | self.ui.parse_tree.setStyle(QStyleFactory.create('windows')) 55 | self.ui.parse_tree.header().setSectionResizeMode(QHeaderView.ResizeToContents) 56 | 57 | 58 | def get_tree(query: str): 59 | tokens, idx, node = query.split(), 0, TreeNode() 60 | while idx < len(tokens): 61 | token = tokens[idx] 62 | if token == 'SELECT' or token == 'PROJECTION': 63 | end = tokens.index(']', idx) 64 | node.op, node.info = token, ' '.join(tokens[idx + 2:end]) 65 | idx = end + 1 66 | elif token == 'JOIN': 67 | node.op = token 68 | node.child.append(TreeNode(info=tokens[idx - 1])) # 连接操作的第一个关系 69 | node.child.append(TreeNode(info=tokens[idx + 1])) # 连接操作的第二个关系 70 | idx += 1 71 | elif token == '(': # 括号内为查询子句,字句所在的子树应该更靠近叶节点 72 | count, idy = 1, idx + 1 73 | while idy < len(tokens) and count > 0: 74 | if tokens[idy] == '(': 75 | count += 1 76 | elif tokens[idy] == ')': 77 | count -= 1 78 | idy += 1 79 | node.child.append(get_tree(' '.join(tokens[idx + 1:idy - 1]))) 80 | idx = idy 81 | else: 82 | idx += 1 83 | return node 84 | 85 | 86 | def output_tree(node: TreeNode, sep=''): 87 | print(sep + str(node)) 88 | if len(node.child) >= 1: 89 | output_tree(node.child[0], sep + '\t') 90 | if len(node.child) >= 2: 91 | output_tree(node.child[1], sep + '\t') 92 | 93 | 94 | def optimize(node: TreeNode, info_lst=None) -> TreeNode: 95 | if node.op == 'SELECT': 96 | node = optimize(node.child[0], node.info.split('&')) 97 | elif node.op == 'PROJECTION': 98 | node.child[0] = optimize(node.child[0], info_lst) 99 | elif node.op == 'JOIN': 100 | node0 = TreeNode(op='SELECT', info=info_lst[0]) 101 | node0.child.append(node.child[0]) 102 | node.child[0] = node0 103 | if len(info_lst) > 1: 104 | node1 = TreeNode(op='SELECT', info=info_lst[1]) 105 | node1.child.append(node.child[1]) 106 | node.child[1] = node1 107 | return node 108 | 109 | 110 | if __name__ == '__main__': 111 | app = QApplication(sys.argv) 112 | main_win = MainWindow(Ui_MainWindow()) 113 | main_win.show() 114 | sys.exit(app.exec_()) 115 | -------------------------------------------------------------------------------- /lab2/relation_operate.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lab2.extmem import disk_dir, tuple_num, blk_num2, blk_num1, Buffer 5 | from math import ceil, floor 6 | from lab2 import extmem 7 | 8 | nlj_dir, blk_num = './disk/join/nlj/', 8 # 关系连接磁盘目录,缓冲区大小 9 | select_dir, project_dir = './disk/select/', './disk/project/' # 关系选择、投影结果所在的磁盘目录 10 | sort_temp_dir, sort_res_dir = './disk/join/sort/sort/', './disk/join/sort/res/' 11 | hash_temp_dir, hash_res_dir = './disk/join/hash/hash/', './disk/join/hash/res/' 12 | 13 | 14 | def linear_search(buffer: extmem.Buffer): # 关系选择:线性搜索R.A=40, S.C=60;并将结果写入到磁盘中 15 | extmem.drop_blk_in_dir(select_dir) # 删除文件夹下的所有模拟磁盘文件 16 | two_items, buffer.io_num, count, res = [('r', extmem.blk_num1, 40), ('s', extmem.blk_num2, 60)], 0, 0, [] 17 | for item in two_items: 18 | for disk_idx in range(item[1]): # item[1]表示关系占用的物理磁盘块数 19 | index = buffer.load_blk('%s%s%d.blk' % (disk_dir, item[0], disk_idx)) # 加载磁盘块内容到缓冲区中 20 | for data in buffer.data[index]: 21 | data0, data1 = data.split() 22 | if int(data0) == item[2]: 23 | res.append(data) # item[2]表示关系选择的结果 24 | if len(res) == tuple_num: 25 | buffer.write_buffer(res, '%s%s%d.blk' % (select_dir, item[0], count)) 26 | res, count = [], count + 1 27 | buffer.free_blk(0) 28 | if res: 29 | buffer.write_buffer(res, '%s%s%d.blk' % (select_dir, item[0], count)) 30 | 31 | 32 | def relation_project(buffer: Buffer): # 关系投影,对R的A属性进行投影并需要去重,并将结果写入到磁盘中 33 | extmem.drop_blk_in_dir(project_dir) # 删除文件夹下的所有模拟磁盘文件 34 | buffer.io_num, res, count, = 0, [], 0 # 投影选择的结果 35 | all_res = set() # todo 排序去重可能属于外排序类型 36 | for disk_idx in range(blk_num1): 37 | index = buffer.load_blk('%sr%d.blk' % (disk_dir, disk_idx)) # 加载磁盘块内容到缓冲区中 38 | for data in buffer.data[index]: 39 | if data.split()[0] not in all_res: 40 | res.append(data.split()[0]) 41 | all_res.add(data.split()[0]) 42 | if len(res) == tuple_num * 2: 43 | buffer.write_buffer(res, '%sr%d.blk' % (project_dir, count)) 44 | res, count = [], count + 1 45 | buffer.free_blk(0) 46 | if res: 47 | buffer.write_buffer(res, '%sr%d.blk' % (project_dir, count)) 48 | 49 | 50 | def nested_loop_join(buffer: extmem.Buffer): 51 | extmem.drop_blk_in_dir(nlj_dir) # 删除文件夹下的所有模拟磁盘文件 52 | res, buffer.io_num, count = [], 0, 0 53 | for outer_idx in range(ceil(blk_num1 / (blk_num - 2))): # 关系R做外层for循环内容 54 | start, end, outer_data = outer_idx * (blk_num - 2), min((outer_idx + 1) * (blk_num - 2), blk_num1), [] 55 | outer_data = [buffer.data[buffer.load_blk('%sr%d.blk' % (disk_dir, idx))] for idx in range(start, end)] 56 | for inner_idx in range(extmem.blk_num2): # 关系S做内层for循环内容 57 | inner_data = buffer.data[buffer.load_blk('%ss%d.blk' % (disk_dir, inner_idx))] 58 | for outer_lst in outer_data: # 内存中执行连接操作 59 | for outer_item in outer_lst: 60 | r_a, r_b = outer_item.split() 61 | for inner_item in inner_data: 62 | s_c, s_d = inner_item.split() 63 | if r_a == s_c: 64 | res.append('%s %s' % (outer_item, inner_item)) 65 | if len(res) == int(tuple_num / 2): 66 | buffer.write_buffer(res, '%srs%d.blk' % (nlj_dir, count)) 67 | res, count = [], count + 1 68 | buffer.free_blk(len(outer_data)) 69 | buffer.data_occupy = [False] * blk_num 70 | if res: 71 | buffer.write_buffer(res, '%srs%d.blk' % (nlj_dir, count)) # 将结果磁盘上的剩余数据写入磁盘 72 | 73 | 74 | def sort_merge_join(buffer: extmem.Buffer): 75 | res, buffer.io_num, all_data = [], 0, [('r', extmem.blk_num1), ('s', extmem.blk_num2)] 76 | for data in all_data: 77 | # 块内排序,由于缓冲区块数^2 < 关系R或S的磁盘块数,可以采用两阶段多路归并算法 78 | num = floor(data[1] / buffer.blk_num) + 1 # 将待排序磁盘块划分为num个集合 79 | if num >= buffer.blk_num: 80 | print('错误,两阶段归并不可行') 81 | return False 82 | for idx in range(num): # 缓冲区的7块放置待排序数据,1块放置排序输出数据 83 | stop, blk_data = ((idx + 1) * (buffer.blk_num - 1)), [] 84 | for idy in range(idx * (buffer.blk_num - 1), stop if stop < data[1] else data[1]): 85 | blk_data.extend(buffer.data[buffer.load_blk('%s%s%d.blk' % (disk_dir, data[0], idy))]) # 加载磁盘块内容到缓冲区中 86 | blk_data = sorted(blk_data, key=lambda item1: int(item1.split()[0])) 87 | for idy in range(int(len(blk_data) / extmem.tuple_num)): 88 | buffer.write_buffer(blk_data[idy * extmem.tuple_num:(idy + 1) * extmem.tuple_num], 89 | '%s%s%d.blk' % (extmem.disk_dir, data[0], idx * extmem.tuple_num + idy)) 90 | buffer.free_blk(idy) 91 | 92 | # 块间排序 93 | count, blk_data, sorted_blk = 0, [[]] * num, [] # count表示已写入磁盘块数 94 | idx_lst = [idx * (buffer.blk_num - 1) for idx in range(num)] # 保存num个索引,用于指向磁盘所在位置 95 | while True: 96 | for idx, item in enumerate(blk_data): 97 | if not item: 98 | buffer.free_blk(idx) 99 | if idx_lst[idx] < min((idx + 1) * (buffer.blk_num - 1), data[1]): # 缓冲区待归并数据已被取空 100 | blk_data[idx] = buffer.data[buffer.load_blk('%s%s%d.blk' % (disk_dir, data[0], idx_lst[idx]))] 101 | idx_lst[idx] += 1 102 | flag = True if len(list(filter(None, blk_data))) else False 103 | if count == data[1] and not flag: # 数据已经遍历完毕且缓冲区中无剩余数据 104 | break 105 | elif flag: # 缓冲区中有剩余数据 106 | index, digit = 0, 1e4 # 找到最小的一个元素 107 | for idx in range(num): 108 | if blk_data[idx] and int(blk_data[idx][0].split()[0]) < digit: 109 | index, digit = idx, int(blk_data[idx][0].split()[0]) 110 | sorted_blk.append(blk_data[index][0]) # 加入到输出缓冲区 111 | blk_data[index].pop(0) 112 | if len(sorted_blk) == extmem.tuple_num: 113 | buffer.write_buffer(sorted_blk, '%s%s%d.blk' % (sort_temp_dir, data[0], count)) 114 | count, sorted_blk = count + 1, [] 115 | 116 | # 执行连接算法 117 | extmem.drop_blk_in_dir(sort_res_dir) # 删除文件夹下的所有模拟磁盘文件 118 | r_idx, s_idx, count, res = 0, 0, 0, [] 119 | r_data = buffer.data[buffer.load_blk('%sr0.blk' % sort_temp_dir)] 120 | s_data = buffer.data[buffer.load_blk('%ss0.blk' % sort_temp_dir)] 121 | while r_idx < blk_num1 * tuple_num and s_idx < blk_num2 * tuple_num: 122 | data0, data2 = int(r_data[r_idx % tuple_num].split()[0]), int(s_data[s_idx % tuple_num].split()[0]) 123 | if data0 == data2: # 先记录原位置,然后向右滑动 124 | res.append('%s %s' % (r_data[r_idx % tuple_num], s_data[s_idx % tuple_num])) 125 | if len(res) == floor(tuple_num / 2): # 结果缓冲区块已满 126 | buffer.write_buffer(res, '%srs%d.blk' % (sort_res_dir, count)) 127 | res, count = [], count + 1 128 | idx_temp = s_idx + 1 # S变量临时向右滑动 129 | while idx_temp < blk_num2 * tuple_num: 130 | if not idx_temp % tuple_num: 131 | buffer.free_blk(1) 132 | s_data = buffer.data[buffer.load_blk('%ss%d.blk' % (sort_temp_dir, floor(idx_temp / tuple_num)))] 133 | if data0 == int(s_data[idx_temp % tuple_num].split()[0]): 134 | res.append('%s %s' % (r_data[r_idx % tuple_num], s_data[idx_temp % tuple_num])) 135 | idx_temp += 1 # 继续滑动 136 | if len(res) == int(tuple_num / 2): # 结果缓冲区块已满 137 | buffer.write_buffer(res, '%srs%d.blk' % (sort_res_dir, count)) 138 | res, count = [], count + 1 139 | else: 140 | break 141 | if floor(idx_temp / tuple_num) > floor(s_idx / tuple_num): # 如果关系S临时滑动到了新的一块 142 | buffer.free_blk(1) 143 | s_data = buffer.data[buffer.load_blk('%ss%d.blk' % (sort_temp_dir, floor(s_idx / tuple_num)))] 144 | idx_temp = r_idx + 1 # 关系R临时向右滑动 145 | while idx_temp < blk_num1 * tuple_num: 146 | if not idx_temp % tuple_num: 147 | buffer.free_blk(0) 148 | r_data = buffer.data[buffer.load_blk('%sr%d.blk' % (sort_temp_dir, floor(idx_temp / tuple_num)))] 149 | if int(r_data[idx_temp % tuple_num].split()[0]) == data2: 150 | res.append('%s %s' % (r_data[idx_temp % tuple_num], s_data[s_idx % tuple_num])) 151 | idx_temp += 1 152 | if len(res) == int(tuple_num / 2): 153 | buffer.write_buffer(res, '%srs%d.blk' % (sort_res_dir, count)) 154 | res, count = [], count + 1 155 | else: 156 | break 157 | if floor(idx_temp / tuple_num) > floor(r_idx / tuple_num): # 如果关系R临时滑动到了新的一块 158 | buffer.free_blk(0) 159 | r_data = buffer.data[buffer.load_blk('%sr%d.blk' % (sort_temp_dir, floor(r_idx / tuple_num)))] 160 | r_idx, s_idx = r_idx + 1, s_idx + 1 # R和S向右滑动 161 | if not r_idx % tuple_num and r_idx < blk_num1 * tuple_num: 162 | buffer.free_blk(0) 163 | r_data = buffer.data[buffer.load_blk('%sr%d.blk' % (sort_temp_dir, floor(r_idx / tuple_num)))] 164 | if not s_idx % tuple_num and s_idx < blk_num2 * tuple_num: 165 | buffer.free_blk(1) 166 | s_data = buffer.data[buffer.load_blk('%ss%d.blk' % (sort_temp_dir, floor(s_idx / tuple_num)))] 167 | elif data0 > data2: 168 | s_idx += 1 169 | if not s_idx % tuple_num and s_idx < blk_num2 * tuple_num: 170 | buffer.free_blk(1) 171 | s_data = buffer.data[buffer.load_blk('%ss%d.blk' % (sort_temp_dir, floor(s_idx / tuple_num)))] 172 | else: 173 | r_idx += 1 174 | if not r_idx % tuple_num and r_idx < blk_num1 * tuple_num: 175 | buffer.free_blk(0) 176 | r_data = buffer.data[buffer.load_blk('%sr%d.blk' % (sort_temp_dir, floor(r_idx / tuple_num)))] 177 | if res: 178 | buffer.write_buffer(res, '%srs%d.blk' % (sort_res_dir, count)) # 将结果磁盘上的剩余数据写入磁盘 179 | 180 | 181 | def hash_join(buffer: extmem.Buffer): 182 | buffer.__init__(blk_num) 183 | extmem.drop_blk_in_dir(hash_temp_dir) 184 | # 对关系R进行hash操作,将缓存中的blk_num-1块作为Hash桶,1块作为输出 185 | hash_num = blk_num - 1 186 | all_data, hash_blk = [('r', blk_num1, [[] for idx in range(hash_num)]), 187 | ('s', blk_num2, [[] for idx in range(hash_num)])], [[] for idx in range(hash_num)] 188 | for item in all_data: 189 | for idx in range(item[1]): 190 | blk_data = buffer.data[buffer.load_blk('%s%s%d.blk' % (disk_dir, item[0], idx))] 191 | for data in blk_data: 192 | hash_idx = int(data.split()[0]) % hash_num 193 | hash_blk[hash_idx].append(data) 194 | if len(hash_blk[hash_idx]) == tuple_num: # HASH桶已满,需要输出 195 | addr = '%s%s%d_%d.blk' % (hash_temp_dir, item[0], hash_idx, len(item[2][hash_idx])) 196 | buffer.write_buffer(hash_blk[hash_idx], addr) 197 | item[2][hash_idx].append(addr) 198 | hash_blk[hash_idx] = [] 199 | buffer.free_blk(0) 200 | for idx in range(hash_num): 201 | if hash_blk[idx]: 202 | addr = '%s%s%d_%d.blk' % (hash_temp_dir, item[0], idx, len(item[2][idx])) 203 | buffer.write_buffer(hash_blk[idx], addr) 204 | item[2][idx].append(addr) 205 | hash_blk[idx] = [] 206 | # 进行连接操作,将缓存中的blk_num-2块保存第i个桶的内容,1块作为输出,1块保存另外1个关系 207 | res, count, buffer.data_occupy = [], 0, [False] * blk_num 208 | extmem.drop_blk_in_dir(hash_res_dir) 209 | for idx in range(hash_num): 210 | r_buffer_data, s_buffer_data, flag = [], [], False 211 | for addr in all_data[0][2][idx]: 212 | r_buffer_data.extend(buffer.data[buffer.load_blk(addr)]) 213 | if ceil(len(r_buffer_data) / tuple_num) == 6: 214 | # todo 更加完善算法,考虑缓冲区大小不足的情况 215 | print('缓冲区大小不足,需要设计算法') 216 | return # 执行分批次连接 217 | for addr in all_data[1][2][idx]: # 将S的第i个hash桶内容逐个加入 218 | s_buffer_data = buffer.data[buffer.load_blk(addr)] 219 | for r_data in r_buffer_data: 220 | for s_data in s_buffer_data: 221 | if r_data.split()[0] == s_data.split()[0]: 222 | res.append('%s %s' % (r_data, s_data)) 223 | if len(res) == int(tuple_num / 2): 224 | buffer.write_buffer(res, '%srs%d.blk' % (hash_res_dir, count)) 225 | res, count = [], count + 1 226 | buffer.free_blk(ceil(len(r_buffer_data) / tuple_num)) 227 | buffer.data_occupy = [False] * blk_num 228 | if res: 229 | buffer.write_buffer(res, '%srs%d.blk' % (hash_res_dir, count)) # 将结果磁盘上的剩余数据写入磁盘 230 | 231 | 232 | def get_res(): # 直接计算自然连接的结果,用于测试其他算法的正确性 233 | all_data, res = [('r', blk_num1, []), ('s', blk_num2, [])], [] 234 | for data in all_data: 235 | for idx in range(data[1]): 236 | with open('%s%s%d.blk' % (disk_dir, data[0], idx), 'r') as f: 237 | data[2].extend(list(map(str.split, f.read().split('\n')))) 238 | for lst1 in all_data[0][2]: 239 | for lst2 in all_data[1][2]: 240 | if lst1[0] == lst2[0]: 241 | res.append(' '.join(lst1 + lst2)) 242 | return res 243 | 244 | 245 | def main(): 246 | buffer = extmem.Buffer(blk_num) 247 | linear_search(buffer) # 关系选择,线性搜索 248 | print('关系选择的磁盘IO次数为:%d' % buffer.io_num) 249 | relation_project(buffer) # 关系投影 250 | print('关系投影的磁盘IO次数为:%d' % buffer.io_num) 251 | nested_loop_join(buffer) 252 | print('nest-loop-join算法的磁盘IO次数为:%d' % buffer.io_num) 253 | sort_merge_join(buffer) 254 | print('sort-merge-join算法的磁盘IO次数为:%d' % buffer.io_num) 255 | hash_join(buffer) 256 | print('hash-join算法的磁盘IO次数为:%d' % buffer.io_num) 257 | print('测试的连接块数为:%d' % ceil(len(get_res()) / int(tuple_num / 2))) 258 | 259 | 260 | if __name__ == '__main__': 261 | main() 262 | --------------------------------------------------------------------------------