简介《zzu数据库实验报告书》是以openGauss为平台的数据库系统原理配套实验合集面向计算机类与软件工程专业在校生、数据库初学者及备考人员。报告按课程教学要求依次完成九个实验认识DBMS系统、创建数据库/表/索引、交互式SQL语句、创建视图、完整性控制、安全性控制、事务与并发控制、备份与恢复以及使用JDBC连接数据库每一步都记录了实验目的、主要仪器材料、操作过程、问题更正和结果分析。整个资源为1份docx文档共1个文件大小3.23MB便于阅读、打印或按实验模块借鉴参考。已有超过1500人浏览学习适合正在修读《数据库系统原理》课程的学生用于考前复习、实验报告撰写或毕业设计前的数据库实操查漏补缺。除操作截图与命令行演示外报告还覆盖了openGauss环境搭建、数据库用户与权限管理、并发控制机制等细节能够帮助读者系统梳理SQL编写与数据库管理的核心要点并为后续开发数据库应用软件打下基础。1. zzu数据库实验报告书是什么一份能过审的实验报告要写什么当你拿到一份“zzu数据库实验报告书”的模板时第一反应多半是找一份现成的实验代码抄进去把表结构一贴SQL一摆交差完事。但真正被老师打回来重写的报告往往不是错在SQL语法而是错在“只有代码没有意图”。数据库实验报告书的核心不是记录你敲了什么命令而是记录你为什么选择这张表、这个字段类型、这个索引以及在调试过程中你踩过哪些坑。它能帮你建立从“会写SQL”到“会设计数据库”的桥梁适合正在上数据库课程、做课程设计、或者想复盘自己实验过程的人。这篇笔记我按实际做实验的顺序来讲环境选型、SQL操作、进阶实验、报告写法、避坑清单最后给你一个验证明白结果的小技巧。2. 搭建数据库实验环境从MySQL到SQLite的选型与最小配置2.1 选型与安装为什么课程实验选MySQL最稳常见的数据库实验环境有MySQL、PostgreSQL、SQLite、SQL Server甚至还有达梦、人大金仓这类国产数据库。如果你是跟着zzu的课程模板走绝大多数实验题目默认的语法是MySQL兼容模式因为MySQL的安装资料多、JDBC驱动好找、Navicat/DBeaver都能直连遇到语法报错时搜索引擎能给出最直接的答案。PostgreSQL也接近标准SQL但有些实验模板里用到的AUTO_INCREMENT、SHOW TABLES这类写法在PostgreSQL里要改成SERIAL和\dt白白增加工作量。SQLite更适合单文件场景但它在并发控制和存储过程上缺了很多功能做事务实验会失真。我一般不建议在这上面花太多时间折腾配置。如果你本机已经装过MySQL直接复用如果还没装下载MySQL Community Server 8.x安装时记住选择“Developer Default”并记好root密码。装完以后把bin目录加到PATH里在命令行里执行mysql -u root -p能进去就算成功。注意MySQL 8默认的认证插件是caching_sha2_password老一点的JDBC驱动不认建议在my.cnf里把default_authentication_plugin改回mysql_native_password或者直接用最新版JDBC驱动。# 以Ubuntu/Debian为例安装MySQL 8的常见做法 sudo apt update sudo apt install mysql-server sudo mysql_secure_installation # 启动服务并检查状态 systemctl start mysql systemctl status mysql这段命令的逻辑很简单先更新软件源再安装服务端然后跑安全配置脚本设置root密码和删除匿名用户。systemctl status mysql是为了确认进程起来而不是卡在某个socket问题。如果你在Windows上用更省事的是直接下载zip解压版然后用管理员权限打开命令行执行mysqld --initialize-insecure初始化数据目录再执行mysqld --console启动之后用空密码进入。2.2 初始化建库建表用一段可复现的SQL模板实验报告里的第一步永远是“建库建表”。很多同学把这一步只用一行CREATE DATABASE带过但老师想看到的是表结构设计时的思考。我常用的做法是先写一段可重复执行的初始化脚本用DROP DATABASE IF EXISTS开头避免上次实验残留数据污染结果。然后用CREATE DATABASE指定字符集再用USE切换。DROP DATABASE IF EXISTS zzu_db_lab; CREATE DATABASE zzu_db_lab CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE zzu_db_lab; DROP TABLE IF EXISTS student; CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 学号, name VARCHAR(50) NOT NULL COMMENT 姓名, gender ENUM(M,F) DEFAULT M COMMENT 性别, birth DATE COMMENT 生日, phone VARCHAR(20) UNIQUE COMMENT 电话, created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学生表;逻辑说明先删后建是为了让实验可以反复重跑报告里应该明确写“本脚本幂等”。ENGINEInnoDB是必须的因为后面做事务和外键实验只有InnoDB支持。utf8mb4比utf8多支持emoji虽然实验里可能用不到但很多数据库版本默认已经是utf8mb4所以直接写上能避免字符集乱码。AUTO_INCREMENT和PRIMARY KEY是主键自增的经典组合。UNIQUE加在phone上是为了演示唯一约束后续插入重复电话时会报错这一行就能引出“约束”知识点。3. 把增删改查写进实验报告SQL操作的具体步骤与输出验证3.1 数据表设计字段类型与约束的常见选择实验报告书里最容易被挑刺的就是字段类型选得“不讲道理”。比如有人用BIGINT存年龄有人用TEXT存手机号虽然能跑但一看就是没理解类型边界。做实验时我习惯按业务含义去选整数类用INT或BIGINT金额用DECIMAL别用FLOAT状态用TINYINT或ENUM描述性长文本用TEXT。日期类型上只需要年月日用DATE需要精确到秒用DATETIME如果怕时区问题就用TIMESTAMP。在实验报告里你不需要解释所有类型但至少要写清楚“为什么性别用ENUM而不是CHAR(1)”——因为数据库层面就能约束非法值不依赖应用层判断。同理电话号码用VARCHAR(20)而不是BIGINT是因为号码开头可能有0而且不需要数值运算。这样写老师一眼就看出你考虑过数据语义而不是随机配对。3.2 增删改查的标准SQL与执行结果记录方法实验报告书一般会要求覆盖增删改查四个操作并给出每次操作的结果。很多同学直接把命令行里的输出截图贴上去这没问题但更专业的做法是把SQL和预期影响行数一起写出来并用SELECT验证。-- 插入三条学生记录 INSERT INTO student (name, gender, birth, phone) VALUES (张三, M, 2000-01-01, 13800000001), (李四, F, 2001-02-02, 13800000002), (王五, M, 1999-03-03, 13800000003); -- 查询所有记录 SELECT id, name, gender, birth, phone FROM student; -- 修改指定记录 UPDATE student SET phone 13900000001 WHERE id 1; -- 删除一条记录 DELETE FROM student WHERE id 3; -- 再次查询确认影响 SELECT COUNT(*) AS cnt FROM student;逻辑说明INSERT后应该用SELECT确认数据真的进去了因为有时候会有触发器静默修改或字符集转码问题。UPDATE一定要带WHERE不带就是全表更新这是实验报告里最经典的翻车案例。DELETE同理。COUNT(*)用来核对当前表行数这样报告里可以记录“插入3行更新1行删除1行剩余2行”的清晰结果。执行结果不要只贴一张截图最好用文本形式记录在报告里老师才能直接看到你的实验数据。3.3 修改表结构ALTER TABLE的几个常用场景数据库实验报告大多包含“修改表结构”这一节对应的热搜词里也恰好有“mysql数据库修改结构”。实验题的常见要求是给学生表增加一个字段、修改字段类型、删除一个字段。这些操作的SQL语法不难难点在于操作前要评估影响。-- 增加一个“班级”字段 ALTER TABLE student ADD COLUMN class_name VARCHAR(50) NOT NULL DEFAULT 计算机1班; -- 修改birth字段类型为datetime ALTER TABLE student MODIFY COLUMN birth DATETIME; -- 删除字段 ALTER TABLE student DROP COLUMN phone;参数说明ADD COLUMN加字段时如果表里有既有数据一定要给DEFAULT否则MySQL会对存量行报错或补默认值。MODIFY COLUMN会重建表如果表很大在实验环境无所谓但报告里可以提一句“生产环境需评估锁表时间”。DROP COLUMN会永久删除该列数据实验报告里建议先备份再执行。这里要特别说明做完这三个操作后立刻用DESC student;查看表结构把这四个状态加前、加后、改后、删后的DESC输出都粘贴到报告里这就是“实验过程记录”的完整证据链。4. 数据库进阶实验事务、视图、存储过程与并发锁4.1 事务的ACID与回滚实验怎么写事务实验是数据库实验报告里的重点章节。老师想看到你理解COMMIT和ROLLBACK的区别并亲眼验证未提交的数据不生效。写法上我建议先用一个“故意失败”的事务展示回滚。-- 开启事务 START TRANSACTION; -- 插入一条临时数据 INSERT INTO student (name, gender, birth) VALUES (赵六, M, 2002-04-04); -- 人为查询当前事务内可见数据 SELECT * FROM student WHERE name 赵六; -- 回滚 ROLLBACK; -- 事务外再查询确认该数据不存在 SELECT * FROM student WHERE name 赵六;这段实验的意义在于告诉你事务内的SELECT能看到未提交的数据但事务外看不到。ROLLBACK后一切恢复原样。实验报告里要记录“事务中是可见的回滚后查询返回空结果”这就完成了隔离性验证。接着再做一个正常提交START TRANSACTION; INSERT INTO student (name, gender, birth) VALUES (钱七, F, 2003-05-05); COMMIT; -- 提交后其他会话也能查到 SELECT * FROM student WHERE name 钱七;注意要验证“其他会话能看到”你需要开两个终端。第一个终端开启事务但不提交第二个终端去查这条数据。这个并发可见性的验证比单纯在一个窗口里敲效果好得多。报告里可以画一张表格记录两个会话各自看到的结果这就是活生生的“读已提交”演示。4.2 视图与索引实验报告里的性能观察点视图和索引是数据库设计的常见考点。实验报告里视图的实验通常很简单创建一个视图查询视图删除视图。但很多同学只写“CREATE VIEW ...”没有说明视图是虚拟表这一本质。我建议在报告里补一个对比基表数据变化后视图结果跟着变。-- 创建学生信息视图 CREATE VIEW v_student AS SELECT id, name, class_name FROM student WHERE gender M; -- 查询视图 SELECT * FROM v_student; -- 修改基表数据 UPDATE student SET name 张三丰 WHERE id 1; -- 再看视图名字已经变了 SELECT * FROM v_student;逻辑说明视图本身不存储数据它只是保存了一个查询定义。所以基表更新视图结果必然更新。这一点写进报告比背“视图是虚拟表”的定义更有说服力。索引实验往往需要一点“性能数据”支撑。你可以在一个有几万行的表上执行EXPLAIN对比有索引和没索引的访问类型type字段和扫描行数rows字段。-- 先建一个测试表并插入大量数据 CREATE TABLE perf_test ( id INT PRIMARY KEY AUTO_INCREMENT, code VARCHAR(32) NOT NULL, name VARCHAR(64) ); -- 用存储过程批量插入数据不止一条 DELIMITER $$ CREATE PROCEDURE insert_perf() BEGIN DECLARE i INT DEFAULT 0; WHILE i 100000 DO INSERT INTO perf_test(code, name) VALUES (CONCAT(code, i), CONCAT(name, i)); SET i i 1; END WHILE; END$$ DELIMITER ; CALL insert_perf(); -- 查看没有索引时的执行计划 EXPLAIN SELECT * FROM perf_test WHERE code code50000; -- 创建索引 CREATE INDEX idx_perf_code ON perf_test(code); -- 再看执行计划 EXPLAIN SELECT * FROM perf_test WHERE code code50000;参数说明DELIMITER是命令行里必不可少的因为存储过程的语句里有分号如果不改分隔符MySQL会在第一个分号处截断。EXPLAIN里type从ALL变成refrows从接近十万行变成一行这就是索引生效的直接证据。报告里写“索引将全表扫描变成普通索引查找”再贴两段EXPLAIN输出老师不可能不给分。4.3 存储过程与触发器参数化实验的加分项实验报告书里如果有存储过程和触发器的题目一定要做因为这是区分“会写SQL”和“懂编程逻辑”的分水岭。存储过程实验的常见要求是“输入学号返回姓名”或者“批量插入数据”。-- 创建存储过程根据id查询学生姓名 DELIMITER $$ CREATE PROCEDURE get_student_name(IN p_id INT, OUT p_name VARCHAR(50)) BEGIN SELECT name INTO p_name FROM student WHERE id p_id; END$$ DELIMITER ; -- 调用 SET name ; CALL get_student_name(1, name); SELECT name;逻辑说明参数分为IN输入、OUT输出、INOUT三种。这里用了IN和OUT配合从调用角度看是“传入一个id拿回一个名字”。SELECT ... INTO是给输出参数赋值的写法。实验报告里要把“定义参数、调用、查看输出参数”三步写清楚并且说明为什么输出参数用前缀的会话变量接收。触发器实验要谨慎因为触发器在后台自动运行出了问题不容易调试。我建议做一个简单的日志表-- 建日志表 CREATE TABLE student_log ( log_id INT PRIMARY KEY AUTO_INCREMENT, operation VARCHAR(10), student_id INT, changed_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 创建后置插入触发器 DELIMITER $$ CREATE TRIGGER trg_student_after_insert AFTER INSERT ON student FOR EACH ROW BEGIN INSERT INTO student_log(operation, student_id) VALUES (INSERT, NEW.id); END$$ DELIMITER ; -- 插入一条数据 INSERT INTO student (name, gender, birth) VALUES (孙八, F, 2004-06-06); -- 查看日志 SELECT * FROM student_log;触发器的关键点AFTER INSERT表示在插入动作成功后再记录日志NEW.id能拿到刚插入的自动生成主键。报告里应该写“触发器不用显式调用插入后log表自动多了一行”。但这里也有个坑如果实验表里已经有多条数据你只插入一次日志表只新增一行要明确区分“执行一次插入”和“历史数据不触发”避免被误认为触发器坏了。5. 数据库实验报告书写避坑指南5条常见问题与解决记录这一章我直接按“现象 → 原因 → 解决”的格式写都是我在带实验课时实际碰到过的或者你自己动手时常见的。5.1 现象使用CREATE DATABASE zzu_db_lab后报字符集错误或中文乱码原因MySQL 8默认字符集是utf8mb4但某些模板创建的库还是latin1或者你用的SQL文件头没有指定SET NAMES utf8mb4。解决建库时显式指定CHARACTER SET utf8mb4连接时在命令行加上--default-character-setutf8mb4。如果用的可视化工具在建库弹窗里把字符集选成utf8mb4。排查技巧执行SHOW CREATE DATABASE zzu_db_lab;查看当前字符集设置不要凭空猜。5.2 现象实验报告里写了DELETE FROM student WHERE id3但运行时报错“Cannot delete or update a parent row”原因这是外键约束在起作用你的表之间有外键关系子表还有未删除的关联数据。很多同学在设计表时习惯把外键约束写在CREATE TABLE里结果到删除实验就翻车。解决可以在实验报告里做一个前置说明——“删除主表记录前先处理子表引用”。具体操作有两种要么先删除子表对应行要么修改外键属性为ON DELETE CASCADE。建议你实验时先用SET FOREIGN_KEY_CHECKS0;临时关闭检查做验证但报告里要写清楚真实场景不推荐这种暴力做法。5.3 现象用UPDATE student SET name 张三丰 WHERE id 1后其他会话查询仍是旧值原因没有提交事务。MySQL默认开启了autocommit但你在同一个会话里可能手动执行了START TRANSACTION却又忘了COMMIT。数据库的可见性受事务隔离级别影响未提交的修改只有当前事务可见。解决检查自己是否开着事务执行COMMIT;或ROLLBACK;。在报告里记录“每次UPDATE后一定要确认是否在事务中”并且养成操作后立刻查询的习惯。5.4 现象存储过程调用时报错“PROCEDURE does not exist”原因你创建的存储过程是在另一个数据库里而当前USE的不是那个库。或者你在同一次连接中创建时没有改动DELIMITER导致存储过程并没有完整创建成功。解决调用前先SHOW PROCEDURE STATUS WHERE Db zzu_db_lab;确认存储过程名和所在库。调用时带上库名写成CALL zzu_db_lab.get_student_name(1, name);。这个坑非常隐蔽因为创建过程时如果分号没处理好MySQL会把后面的语句当独立SQL解释所以报告里必须保存创建成功的证据比如执行完DELIMITER后没有报错。5.5 现象EXPLAIN显示索引没有被使用原因常见于你查询的字段和索引列的类型不一致比如索引是VARCHAR但条件里写了WHERE code 50000数字类型会让索引失效。或者你在查询列上用了函数WHERE DATE(birth) 2000-01-01就不能用birth上的索引。解决保持类型一致避免在条件列上套函数。实验报告里可以把这两种情况都写进去对比EXPLAIN结果反而是一个更深度的实验点。6. 用自动化脚本核验实验报告从数据检查到结果留痕的技巧实验报告交出去之前我习惯写一个简单的Python脚本把报告中涉及的所有表和关键查询重新跑一遍确认数据、约束、事务行为都还在。这个小脚本的作用不是代替MySQL而是给自己留一条“后悔药”万一改错了还能快速回到初始状态。import mysql.connector # 连接数据库参数根据实际环境修改 conn mysql.connector.connect( host127.0.0.1, userroot, passwordyour_password, databasezzu_db_lab ) cursor conn.cursor() # 检查学生表是否存在且表结构正确 cursor.execute(SHOW TABLES LIKE student) assert cursor.fetchone() is not None, 缺少student表 # 验证约束插入重复电话应报错 try: cursor.execute(INSERT INTO student (name, phone) VALUES (测试, 13800000001)) conn.rollback() print(约束异常重复电话插入成功) except mysql.connector.Error: print(唯一约束生效) # 验证事务回滚 cursor.execute(START TRANSACTION) cursor.execute(INSERT INTO student (name) VALUES (临时)) cursor.execute(ROLLBACK) cursor.execute(SELECT COUNT(*) FROM student WHERE name 临时) assert cursor.fetchone()[0] 0, 回滚未生效 cursor.close() conn.close() print(全部检查通过)这个脚本的核心是自动断言如果某一步的结果和别人报告的“预期结果”不一致脚本会直接抛异常。比如唯一约束那段正常情况下会捕获到mysql.connector.Error如果没捕获到说明表定义里的UNIQUE没生效。事务回滚那段如果回滚后还能查出来说明隔离级别或事务控制出了问题。报告里你可以把脚本的输出文本附上作为“实验结果可复现”的证明。我的习惯是每做完一个实验小节就运行一次这个小脚本而不是等到全部写完再一次性验收。因为数据库实验最怕的就是前面的积累影响了后面尤其是有外键和触发器的时候早发现问题早解决。另外如果你用的是SQLite做实验把mysql.connector换成sqlite3连接参数改成文件路径即可但要注意很多语法和类型不兼容所以我不建议用自动化脚本跨数据库跑同一套SQL。最后给你一个写报告书的小技巧每一章实验都按“实验目的 → 实验环境 → 实验内容 → 实验结果 → 问题与思考”来组织其中“问题与思考”是你区别于其他报告的最大加分项。不要怕写自己翻车的过程比如误删了数据、索引失效、事务没提交这些真实踩坑记录反而比完美的结果更有说服力。希望这些从搭建环境到核验结果的实战经验能帮到你祝你的数据库实验报告一次性过审。本文还有配套的精品资源点击获取