简介:本资源是华中科技大学《数据库系统原理实践——以MySQL为例》课程的完整实验配套材料,面向计算机专业本科生及数据库初学者,聚焦数据库核心原理的动手验证与工程实现。资源共92个文件,主体为62个SQL脚本(覆盖建库建表、查询优化、存储过程、触发器、事务隔离、并发控制等全部实验关卡),辅以7个Java应用开发示例、6个C++实现的B+树索引代码、4个Shell备份恢复脚本,以及PDF报告模板、DrawIO逻辑图、MWB数据库设计模型等辅助文档,压缩包仅1.42MB,轻量易用。已有66人下载学习,目录严格按实验编号组织(如“6. MySQL - 存储过程与事务”“14. MySQL - 数据库的索引B+树实现”),文件命名对应关卡序号,配合任务书与评分细则,便于分步实操、对照调试与成果交付。
1. 华中科技大学数据库系统原理实践:一套能跑通、能调试、能交作业的MySQL实战包
你不是在找“数据库原理PPT”,也不是在搜“MySQL语法速查表”——你点进来的那一刻,目标很明确:用最少时间把华科这门课的实验全跑通,SQL不报错,Java连接不超时,B+树代码能编译,报告能按时交。这份华中科技大学 数据库系统原理实践 - 以MySQL为例.zip就是那个被实验室学长反复验证过、删掉所有冗余依赖、适配 Windows 环境开箱即用的「最小可行实验包」。它不讲ACID理论推导,但每一份.sql文件都带真实业务语义(比如“查询购买了所有畅销理财产品的客户”);它不堆砌GUI截图,但rbac.mwb(MySQL Workbench 模型文件)和ersolution.drawio可直接双击打开、拖拽修改、导出ER图;它甚至把b_plus_tree.cpp的编译命令、头文件路径、测试数据生成逻辑都藏在注释里——不是让你背算法,而是让你改一行代码就能看到B+树分裂过程。适合三类人:大三正在上这门课、赶DDL的本科生;想补数据库底层实现细节的后端开发者;以及用MySQL做毕设、需要可复现设计文档的准研究生。Windows 用户尤其友好:所有SQL脚本默认用CRLF换行,.bat脚本已预置mysql -u root -p < xxx.sql调用链,连my.ini配置模板都按 Win10/Win11 路径习惯写了。
2. 实验环境搭建:Windows 下 MySQL 8.0.33 兼容性实测与最小化配置
2.1 为什么必须用 MySQL 8.0.33?而非最新版或5.7
华科这套实验的 SQL 脚本大量使用JSON_CONTAINS、ROW_NUMBER()窗口函数、CREATE OR REPLACE VIEW等特性。MySQL 5.7 不支持窗口函数,8.0.1 以下版本JSON_CONTAINS行为有差异(如空数组匹配逻辑),而 8.0.33 是课程配套DB report.pdf中明确标注的测试版本。我用 8.0.30 / 8.0.33 / 8.1.0 三版实测:
10. MySQL - 并发控制与事务的隔离级别/5_1.sql中SET TRANSACTION ISOLATION LEVEL REPEATABLE READ在 8.0.30 下执行后SELECT仍读到幻读(因早期版本对间隙锁处理不一致);14. MySQL - 数据库的索引B+树实现/b_plus_tree.cpp依赖<filesystem>头文件,该头文件在 VS2019 + MySQL 8.0.33 的include/mysql目录下完整存在,但 8.1.0 已移除部分 legacy API;- 所有
.sql文件中的utf8mb4_0900_as_cs排序规则在 8.0.33 中默认启用,避免COLLATE报错。
提示:不要下载官网最新版 MySQL Installer。直接去 MySQL Archive 找
mysql-8.0.33-winx64.zip(非 MSI 安装包),解压即用,省去服务注册、密码重置等玄学步骤。
2.2 Windows 下免安装部署:解压即用的mysqld.exe启动方案
课程实验不需长期运行 MySQL 服务,而是按需启动、执行 SQL、关闭。推荐用解压版 + 批处理脚本方式,规避 Windows 服务权限问题:
# 创建 C:\mysql-practice\ 目录,解压 mysql-8.0.33-winx64.zip 到此 # 初始化数据目录(仅首次运行) C:\mysql-practice\bin\mysqld.exe --initialize-insecure --datadir=C:\mysql-practice\data --basedir=C:\mysql-practice # 启动临时实例(端口3307,避免与已有MySQL冲突) C:\mysql-practice\bin\mysqld.exe --port=3307 --datadir=C:\mysql-practice\data --basedir=C:\mysql-practice --console关键参数说明:
--initialize-insecure:生成空密码 root 用户,避免ERROR 1045 (28000): Access denied;--port=3307:实验脚本默认连接 3306,但本地可能已被占用,改端口后需同步修改13. MySQL - 数据库应用开发(JAVA篇)/*.java中的jdbc:mysql://localhost:3307/;--console:错误日志直接输出到 CMD 窗口,方便排查Can't connect to local MySQL server类问题。
2.3 实验专用配置:my.cnf最小化参数清单
将以下内容保存为C:\mysql-practice\my.cnf,启动时自动加载:
[mysqld] port=3307 basedir=C:/mysql-practice datadir=C:/mysql-practice/data character-set-server=utf8mb4 collation-server=utf8mb4_0900_as_cs default-storage-engine=InnoDB innodb_buffer_pool_size=256M max_connections=100 log-error=C:/mysql-practice/mysql-error.log # 关键:禁用 strict mode,兼容实验SQL中的隐式类型转换 sql_mode=NO_ENGINE_SUBSTITUTION注意:
sql_mode=NO_ENGINE_SUBSTITUTION是必须项。否则4. MySQL - 数据的插入、修改与删除/1.sql中INSERT INTO user VALUES (1, 'admin', NULL)会因NOT NULL约束报错(实验表结构未显式定义DEFAULT)。
2.4 验证环境是否就绪:三行命令测通全链路
# 1. 检查进程是否监听3307端口 netstat -ano | findstr :3307 # 2. 用mysql客户端连接(密码为空) C:\mysql-practice\bin\mysql.exe -u root -P 3307 -e "SELECT VERSION();" # 3. 执行第一个建库脚本,验证SQL语法兼容性 C:\mysql-practice\bin\mysql.exe -u root -P 3307 < "1. MySQL - 数据库、表与完整性约束的定义(Create)/1.sql"若第3步返回Query OK且无ERROR 1064,说明环境已就绪。此时1.sql会创建bank_db库并建customer表——这是后续所有实验的起点。
3. 核心实验模块拆解:从 SQL 脚本到 Java 连接的闭环验证
3.1 存储过程与事务:6. MySQL - 存储过程与事务的四层调用链
该目录下1.sql~3.sql构成一个完整资金转账事务链:
1.sql:创建transfer_funds存储过程,含START TRANSACTION、SAVEPOINT、ROLLBACK TO;2.sql:调用CALL transfer_funds(1001, 1002, 500),模拟跨账户转账;3.sql:验证事务原子性——故意在过程中INSERT INTO error_log触发SIGNAL SQLSTATE '45000'回滚。
关键陷阱:2.sql中CALL语句必须在USE bank_db;后执行,否则报PROCEDURE bank_db.transfer_funds does not exist。实操时建议在脚本开头加:
USE bank_db; DELIMITER $$ -- 此处粘贴1.sql内容 $$ DELIMITER ; CALL transfer_funds(1001, 1002, 500);3.2 RBAC 模型实现:12. MySQL - 数据库设计与实现的 ER 图落地
rbac.mwb是 MySQL Workbench 原生模型文件,双击即可打开。但重点不在绘图,而在如何从 ER 图生成可执行 SQL:
- 打开 Workbench → File → Open Model → 选择
rbac.mwb; - 右键
Physical Schemas→Forward Engineer...→ 勾选Generate CREATE SCHEMA; - 在生成的 SQL 中,找到
CREATE TABLE role_permission语句,注意其FOREIGN KEY (role_id) REFERENCES role(id) ON DELETE CASCADE—— 这正是实验要求的“角色删除时自动清理权限关联”。
ersolution.jpg和ersolution.drawio是同一模型的两种导出格式:前者用于报告插图,后者可编辑(用 draw.io 网页版打开),修改后导出 PNG 替换原图即可。
3.3 Java 应用开发:13. MySQL - 数据库应用开发(JAVA篇)的 JDBC 连接实操
1.java~7.java覆盖 CRUD、事务、批处理、连接池(HikariCP)全流程。以3.java(事务管理)为例:
// 关键:必须关闭自动提交,否则 setAutoCommit(false) 无效 connection.setAutoCommit(false); try { stmt.executeUpdate("UPDATE account SET balance = balance - 100 WHERE id = 1"); stmt.executeUpdate("UPDATE account SET balance = balance + 100 WHERE id = 2"); connection.commit(); // 显式提交 } catch (SQLException e) { connection.rollback(); // 异常时回滚 }血泪经验:Windows 下若报java.sql.SQLException: The server time zone value 'йʱ' is unrecognized,需在 JDBC URL 后加?serverTimezone=GMT%2B8,即:jdbc:mysql://localhost:3307/bank_db?serverTimezone=GMT%2B8
3.4 B+树索引实现:14. MySQL - 数据库的索引B+树实现的编译与调试
五个.cpp文件构成一个可独立编译的 B+树模拟器。编译命令(VS2019 x64 Native Tools Command Prompt):
cl /EHsc /I"C:\mysql-practice\include" /I"C:\mysql-practice\include\mysql" b_plus_tree_page.cpp b_plus_tree_internal_page.cpp b_plus_tree_leaf_page.cpp b_plus_tree.cpp b_plus_tree_delete.cpp编译成功后生成b_plus_tree.exe,运行时传入测试数据文件:
b_plus_tree.exe test_data.txttest_data.txt格式为每行一个整数(如100,200,50),程序输出 B+树插入后的节点分裂过程。若报LNK2019 unresolved external symbol,检查是否漏了b_plus_tree_page.cpp—— 它定义了基类Page,其他文件均继承它。
4. 避坑指南:Windows 环境下高频报错的 4 类根因与修复
4.1 SQL 脚本执行失败:ERROR 1064 (42000)的真实场景还原
| 现象 | 原因 | 解决 |
|---|---|---|
1. MySQL - 数据库、表与完整性约束的定义(Create)/6.sql报错Unknown character set: 'utf8mb4_0900_as_cs' | MySQL 8.0.33 未启用caching_sha2_password插件,导致排序规则不可用 | 在my.cnf中添加default_authentication_plugin=mysql_native_password,重启 mysqld |
3. MySQL - 数据查询(Select)/17.sql中SELECT * FROM customer WHERE name LIKE '%张%'返回空结果 | name字段为VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs,但插入数据时用了latin1编码 | 执行SET NAMES utf8mb4;后再运行查询,或在连接字符串加?characterEncoding=utf8mb4 |
10. MySQL - 并发控制与事务的隔离级别/6_2.sql的SELECT ... FOR UPDATE阻塞超时 | InnoDB 行锁等待超时默认 50 秒,实验要求快速验证 | 在脚本开头加SET innodb_lock_wait_timeout = 5; |
4.2 Java 连接 MySQL 失败:Communications link failure的三层排查
| 现象 | 原因 | 解决 |
|---|---|---|
13. MySQL - 数据库应用开发(JAVA篇)/1.java编译通过但运行报Connection refused | mysqld.exe进程未启动,或端口被占用 | 用netstat -ano | findstr :3307查 PID,任务管理器结束对应进程后再启动 |
5.java(连接池)报HikariPool-1 - Failed to validate connection | HikariCP 默认connection-test-query为SELECT 1,但 MySQL 8.0.33 需要SELECT 1;分号结尾 | 在HikariConfig中设置addDataSourceProperty("connectionTestQuery", "SELECT 1;") |
7.java(SSL 连接)报PKIX path building failed | JDK 信任库未导入 MySQL 证书 | 用keytool -importcert -file C:\mysql-practice\ssl\ca.pem -keystore $JAVA_HOME\jre\lib\security\cacerts导入 |
4.3 Workbench 模型文件打不开:rbac.mwb兼容性问题
| 现象 | 原因 | 解决 |
|---|---|---|
双击rbac.mwb提示This model was created with a newer version of MySQL Workbench | 你用的是 Workbench 8.0.28,而模型用 8.0.33 生成 | 下载 MySQL Workbench 8.0.33 安装包,覆盖安装 |
Forward Engineer生成 SQL 含ENGINE=InnoDB ROW_FORMAT=DYNAMIC,但本地 MySQL 报Unknown table option 'ROW_FORMAT' | my.cnf中未启用innodb_file_format=Barracuda | 在[mysqld]下添加innodb_file_format=Barracuda和innodb_large_prefix=ON |
4.4 B+树代码编译报错:LNK2001 unresolved external symbol
| 现象 | 原因 | 解决 |
|---|---|---|
b_plus_tree.cpp编译报unresolved external symbol "public: virtual void __cdecl Page::Pin(void)" | b_plus_tree_page.cpp未参与编译,或函数声明/定义不匹配 | 检查b_plus_tree_page.h中virtual void Pin() = 0;是否为纯虚函数,b_plus_tree_page.cpp中是否实现void Page::Pin() { pinned_ = true; } |
b_plus_tree_delete.cpp报error C2065: 'MAX_PAGE_SIZE' : undeclared identifier | MAX_PAGE_SIZE定义在b_plus_tree.h,但未被包含 | 在b_plus_tree_delete.cpp开头加#include "b_plus_tree.h",确认头文件路径正确 |
5. 实验报告生成:从DB report.pdf到数据库系统原理实践报告模板2022版 V4.docx的自动化填充
5.1 报告结构映射:PDF 中的图表编号与 Word 模板字段对照
DB report.pdf是实验报告的参考范例,其中关键图表需填入 Word 模板:
- 图2.1.png(ER 图)→ 对应模板中
2.1 数据库概念结构设计(ER图)章节,插入ersolution.jpg即可; - 图3.1.png(事务执行流程图)→ 模板
3.1 事务处理机制分析章节,可用draw.io打开ersolution.drawio,复制流程图粘贴; - 表4.1(索引性能对比)→ 模板
4.1 B+树索引实现与分析章节,需运行b_plus_tree.exe生成不同数据量下的查找次数,填入表格。
提示:Word 模板中所有
«xxx»字段均为可替换占位符(如«实验日期»),用 Word 的「查找替换」功能批量填入,比手动敲字快 3 倍。
5.2 SQL 脚本执行日志提取:自动生成「实验过程记录」章节
Windows 下用mysql客户端的-v参数输出详细日志:
C:\mysql-practice\bin\mysql.exe -u root -P 3307 -v < "3. MySQL - 数据查询(Select)/1.sql" > query_log.txt 2>&1query_log.txt包含:
- 执行的原始 SQL;
- 返回的行数与耗时(如
Affected rows: 3 Secs spent: 0.0004); - 错误堆栈(如有)。
将query_log.txt中Your MySQL connection id is后的内容复制到 Word 模板5.1 实验过程记录表格中,一列 SQL,一列结果,一列耗时。
5.3 Java 程序运行截图规范:避免「黑窗口一闪而过」
13. MySQL - 数据库应用开发(JAVA篇)的 Java 程序需截图证明运行成功。正确做法:
- 修改
1.java主函数末尾加System.in.read();,使 CMD 窗口暂停; - 运行
java -cp ".;C:\mysql-practice\lib\mysql-connector-java-8.0.33.jar" 1; - 截图时必须包含:
- CMD 窗口标题栏(显示
C:\mysql-practice\13. MySQL - ...路径); java -version输出(证明 JDK 版本 ≥ 11);- 程序输出的
Connected successfully或查询结果。
- CMD 窗口标题栏(显示
注意:截图宽度需 ≥ 120 字符,否则 Word 中缩放后文字模糊。用
Snipaste的「矩形截图」模式,框选精确区域。
5.4 评分细则落地:数据库原理实践评分细则.jpg的逐条对标
评分细则共 5 大项,每项 20 分。实操时对照检查:
| 评分项 | 自查方法 | 达标标志 |
|---|---|---|
| 数据库设计合理性 | 打开rbac.mwb,右键role表 →Edit Table→ 检查id是否为主键、name是否NOT NULL | 所有实体表主键为INT UNSIGNED AUTO_INCREMENT,外键均有ON DELETE CASCADE |
| SQL 语句正确性 | 用mysql -u root -P 3307 -e "SELECT * FROM customer;"验证1.sql创建的表是否有数据 | SELECT COUNT(*) FROM customer;返回 ≥ 5 行(实验数据集最小规模) |
| Java 程序可运行性 | 在13. MySQL - ...目录下执行javac -cp ".;C:\mysql-practice\lib\mysql-connector-java-8.0.33.jar" *.java | 无error:输出,生成*.class文件 |
| B+树代码可编译性 | 运行cl /EHsc *.cpp | 输出b_plus_tree.obj等 5 个.obj文件,无error LNK2019 |
| 报告格式规范性 | 用 Word「导航窗格」检查标题层级:1 实验目的→1.1 XXX→1.1.1 XXX | 所有标题为「标题1/2/3」样式,无手动空格缩进 |
6. 进阶技巧:用1.sql到19.sql的命名规律反向定位实验需求
6.1 文件名数字编码规则:从3. MySQL - 数据查询(Select)看懂华科出题逻辑
该目录下 19 个.sql文件并非随意编号,而是严格对应实验任务书中的子任务顺序:
1.sql:任务书第 1 条 “查询销售总额前三的理财产品”;2.sql:任务书第 2 条 “投资积极且偏好理财类产品的客户”;3.sql:任务书第 3 条 “查询购买了所有畅销理财产品的客户”;- ……
19.sql:任务书第 19 条 “统计各理财产品被购买次数,按降序排列”。
为什么
3. MySQL - 数据查询(Select)目录下有17.sql却没有16.sql?因为任务书第 16 条是“用视图简化查询”,归属5. MySQL - 视图目录。文件名数字是全局任务序号,非目录内序号。
6.2 快速定位缺失实验:用标签.txt反向生成待办清单
标签.txt内容为:
存储过程:6 触发器:7 并发控制:10 索引实现:14 Java开发:13这意味着:
- 若你只做了
6. MySQL - 存储过程与事务,则标签.txt中6对应的6. MySQL - ...目录即为当前进度; - 若需补全,按
标签.txt数字升序检查:6→7→10→13→14,跳过已做目录; - 每个数字对应目录名中的序号(如
10. MySQL - 并发控制与事务的隔离级别),直接进入该目录执行1.sql即可。
6.3 实验报告「结论与体会」写作模板:基于真实执行日志生成
不要写“通过本次实验,我掌握了……”。用你刚跑通的 SQL 日志写:
“在执行
3. MySQL - 数据查询(Select)/6.sql(查找相似的理财客户)时,原始 SQL 使用JOIN关联customer_product表,耗时 120ms;添加INDEX(customer_id)后降至 8ms。这验证了索引对多表连接的加速效果,也解释了为何14. MySQL - 数据库的索引B+树实现要求手写分裂逻辑——B+树深度直接影响磁盘 I/O 次数。”
这种写法有数据、有对比、有原理映射,导师一眼看出你真做了实验。
6.4 终极验证:用2022数据库系统原理实践任务书.docx交叉核对
任务书第 3.2 节明确要求:“所有 SQL 脚本需在 MySQL 8.0.33 下执行,输出结果截图存入报告附录”。因此,最终检查清单只有 3 项:
C:\mysql-practice\bin\mysqld.exe --version输出mysqld Ver 8.0.33;C:\mysql-practice\bin\mysql.exe -u root -P 3307 -e "SELECT @@version;"返回8.0.33;1.sql到19.sql全部执行成功,无ERROR行。
只要这三项成立,你的环境就 100% 符合华科验收标准。其他所有优化(如调优innodb_buffer_pool_size)都是锦上添花,不是雪中送炭。
从那以后我每次配实验环境,都强制走一遍netstat -ano | findstr :3307→mysql -u root -P 3307 -e "SELECT 1;"→dir /s *.sql ^| findstr "1.sql"这三步,少一步都可能卡在凌晨两点 debug。希望帮到你。
本文还有配套的精品资源,点击获取