简介:一份面向太原理工大学软件工程专业《数据库概论》课程的实验报告,适合正在学习SQL Server 2016交互式SQL、数据完整性与用户控制的在校生参考。报告按实验目的、平台、主要内容和结果展开,完整记录了基本表的创建/修改/删除、索引与视图构建,以及插入、修改数据等核心操作的SQL语句和运行结果。压缩包为单个docx文档,共1个文件,大小1.69MB,便于直接阅读和对照练习;已有311人学习。资源内容具体列出了Student、Course、Sc等表结构及多行插入、条件更新等典型操作,能够帮助梳理数据库对象操作与约束设置思路,也可作为完成同类实验或课程报告的实用模板。
1. 数据库概论实验报告:为什么照着课本敲完 SQL 反而拿了低分
软件工程专业的数据库概论课,期末总评里实验报告通常占 20 到 30 分。很多人以为这门课的实验就是“把课本上的 SQL 抄进客户端,截图交上去”,结果发现同样是交了报告,有人拿优秀,有人被退回重写。差距不在 SQL 跑没跑通,而在报告里有没有体现出“你理解了这个数据库问题”。这篇笔记想讲的,就是把“太原理工大学 - 软件工程 - 数据库概论 - 实验报告”这样一个课程作业,拆成一套可以照着做的完整流程:从实验设计、环境搭建、建表 SQL,到报告写作和答辩验证。新手可以按步骤走,已经写完报告但心里没底的人,也能靠中间几章的避坑点自查一遍。
2. 动手前先拆题:实验范围、评分维度和数据库选型怎么定
大部分同学拿到实验指导书的第一反应是打开数据库客户端开始敲代码,这其实顺序反了。数据库概论实验报告要想拿高分,第一步不是写 SQL,而是把“这门课到底要考什么”拆清楚。指导书里列了十几个实验题目,但评分老师真正看的是四件事:数据建模能力、SQL 编写能力、完整性约束意识,以及排查问题的记录。先拆题,后面每一步都省时间。
2.1 课程实验范围:从建库到触发器,哪些是及格项哪些是加分项
数据库概论的实验设置一般分四个梯队,对应不同的给分权重。第一梯队是 SQL 基础,包括建库、建表、增删改查和简单的连接查询,这是及格线。第二梯队是完整性约束,主键、外键、唯一约束、检查约束,这些决定了表结构是不是“规范”的,属于中等分。第三梯队是索引和视图,常被包装成“查询性能优化”和“安全访问控制”两个题目,属于拉开差距的部分。第四梯队是事务和存储过程,通常只在最后一个实验里出现,作为综合应用。
对照实验指导书,把每个实验题目按这个梯队标一个级别,你会发现大多数人都卡在第二梯队和第三梯队之间。常见的问题是表建出来了,但外键没加、自定义约束没写,导致后面做连接查询时结果正确但逻辑不严谨。评分老师看报告时不会只跑一遍查询,他会看你的建表语句里有没有故意设计约束,因为这代表你有没有把课上讲的“完整性”概念落到实践里。
建议拿到指导书后先花半小时做一件事:把所有实验题目的知识点列一张表,标注“题目在考什么”和“我会哪一步”,把不会的标成红色。这张表不放进报告,但它是你后面两周的实验计划。别跳过这个动作,我见过太多人做实验一的时候花了大量时间调环境,后面实验五的实验只剩一晚通宵,报告质量自然不稳定。
2.2 选型理由:课堂讲的是 SQL Server,实验为什么推荐 MySQL
很多学校的数据库课用 SQL Server 做教学演示,学生就跟着在 Windows 上装 SQL Server,这没问题,但不一定是最省事的选择。我的建议是:课堂上用什么演示,实验就用什么,除非你遇到了硬件或兼容性问题。因为实验报告的可信度来自“结果可复现”,如果你用一套和课堂不一致的环境,出了问题没人能帮你排查。
如果课程没有强制指定数据库产品,优先 MySQL。原因有三个:第一,MySQL 8.0 的安装包小、文档全,遇到报错基本能搜到答案;第二,它支持标准的 SQL 语法,和外键、视图、事务相关的实验需求完全对齐;第三,可视化工具 MySQL Workbench 和命令行客户端都能用,截图效果清晰,适合放进报告。要是你用的是某国产数据库或教学专用的简化版客户端,也问题不大,核心 SQL 语句基本兼容。
需要注意一个细节:实验报告里一定要写清楚“数据库产品、版本号、客户端工具”这三项信息。评分老师看到 MySQL 8.0 和看到“某个教学平台自带数据库”的信任度完全不同。这个信息放在报告开头的实验环境一节里,两行字就能让报告显得专业。
2.3 本地环境十分钟就绪:MySQL 8 安装与最小配置
环境搭建不值得花超过半小时。如果半小时还没装好,说明卡在某个配置点上了,直接看报错信息去对应解决,别反复卸载重装。下面是我在 Windows 上装 MySQL 8 时常用的最小步骤,Linux 和 macOS 略有差异,但思路一致。
# 1. 下载 MySQL Community Server 8.0 的 ZIP 包,解压到 D:\mysql-8.0 # 2. 在 D:\mysql-8.0 下新建 my.ini,内容如下 [mysqld] basedir=D:/mysql-8.0 datadir=D:/mysql-8.0/data port=3306 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci default-storage-engine=INNODB [client] default-character-set=utf8mb4 # 3. 以管理员身份打开命令提示符,进入 bin 目录 mysqld --initialize-insecure # 这条命令会初始化数据目录,--initialize-insecure 表示初始 root 密码为空 mysqld --install MySQL80 net start MySQL80 # 安装为 Windows 服务并启动 mysql -u root -p # 密码为空,直接回车登录这段脚本里有三个关键参数。port=3306是 MySQL 默认端口,如果这个端口被占用,后面的连接全部失败,最常见的冲突来源是某些安全软件或另一个数据库实例。character-set-server=utf8mb4设置了建表默认字符集,这一步直接决定你后面插入中文数据时会不会乱码,很多同学建表时报错或者查询结果出现问号,就是这里没配。default-storage-engine=INNODB是关键,InnoDB 支持事务和外键,实验里的“事务”题目必须有它,MyISAM 不支持,所以别改成别的存储引擎。
初始化完成后,建议顺手建一个专门做实验的账号,不要一直用 root。因为有些实验报告里要写“不同用户的权限不同”,到时候现成账号就能直接演示授权语句。比如创建一个叫db_exp的用户,只给实验库的权限,报告中权限管理的部分就能写得更真实。登录成功后,先跑一条SELECT VERSION();确认版本,截图存好,这个截图放进实验报告的“实验环境”小节非常加分。
3. 把实验需求翻译成建表 SQL:语义分析、约束与查询落地
环境就绪后,核心工作就是把实验指导书里的需求变成一张张表。这一步难的不是 SQL 语法,而是语义理解。比如题目说“一个学生可以选修多门课程,一门课程可以被多个学生选修,选课要记录成绩”,这背后就是学生表和课程表之间的多对多关系,必须拆出一张选课表。很多报告翻车就翻在这里:照着需求建了三张表,却把成绩字段放进了学生表,导致后续查询要么写不出来,要么写出来很别扭。
3.1 从 E-R 模型到关系模式:三句话找到主键和外键
我习惯在写 SQL 之前先在纸上画 E-R 图,哪怕画得很潦草。实体画方框,属性画椭圆,联系画菱形,连线标上 1 对多还是多对多。这个图不一定要放进报告,但它能帮你把语义理清楚。判断主键和外键有三个经验法则:每个实体找一个能唯一标识一条记录的属性作为主键;如果找不到,就加一个自增 id;两个实体之间有 1 对 N 关系时,在 N 端加外键引用 1 端的主键。
举一个最常见的“学生-课程-选课”例子。学生实体有学号、姓名、专业、入学年份;课程实体有课程号、课程名、学分、任课教师;选课联系上有成绩属性。转换成关系模式就是三张表:学生表(学号为主键),课程表(课程号为主键),选课表(学号加课程号联合作为主键,同时学号和课程号分别作为外键)。选课表不能单独用学号做主键,因为一个学生选多门课,学号会重复;也不能单独用课程号,一门课有多个人选。这个细节在实验报告里写一句“联合主键用于表达选课的唯一性”,就是专业性的体现。
很多同学会在这里犯一个错:把成绩字段放在选课表没问题,但把成绩放在学生表里就是错的。因为一个学生有多门课的成绩,放在学生表里会导致学生表出现重复行,违反第一范式。这个点经常以简答题形式出现在实验报告的思考题里,写报告时值得单独展开一段。
3.2 一份能直接提交的建库建表脚本:约束、索引与数据类型
下面这份 SQL 脚本是我做“学生选课系统”实验时常用的模板,覆盖了建库、建表、外键、检查约束、唯一约束和索引。你可以直接改表名和字段名,用到自己的实验题目里。注意观察每一段注释,评分老师看建表语句时就是在找你写过这些注释。
-- 创建实验数据库,指定字符集避免中文乱码 CREATE DATABASE IF NOT EXISTS db_student_course DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; USE db_student_course; -- 学生表:学号作为业务主键,姓名不能为空 CREATE TABLE student ( sno CHAR(10) PRIMARY KEY, -- 学号,固定长度字符,避免字符串比较时尾部空格问题 sname VARCHAR(20) NOT NULL, -- 姓名,VARCHAR 按内容长度存储,节省空间 gender CHAR(1) DEFAULT '男', major VARCHAR(50), enroll_year YEAR, CONSTRAINT chk_gender CHECK (gender IN ('男', '女')) -- 检查约束,防止非法数据写入 ); -- 课程表:课程号为主键,学分限制在 1 到 10 之间 CREATE TABLE course ( cno CHAR(6) PRIMARY KEY, cname VARCHAR(50) NOT NULL, credit DECIMAL(3,1), teacher VARCHAR(20), CONSTRAINT chk_credit CHECK (credit > 0 AND credit <= 10) ); -- 选课表:联合主键保证同一学生同一课程只选一次 CREATE TABLE enroll ( sno CHAR(10), cno CHAR(6), score DECIMAL(5,2), PRIMARY KEY (sno, cno), -- 联合主键,表达“一个学生选一门课”的唯一性 FOREIGN KEY (sno) REFERENCES student(sno) ON DELETE CASCADE, FOREIGN KEY (cno) REFERENCES course(cno) ON DELETE CASCADE, CONSTRAINT chk_score CHECK (score >= 0 AND score <= 100) ); -- 为选课表的成绩字段加索引,后续按成绩查询和排序会明显变快 CREATE INDEX idx_enroll_score ON enroll(score);这段 SQL 里有几个值得展开的参数选择。CHAR(10)和VARCHAR(20)的差别是:学号长度固定,用 CHAR 不会浪费空间且比较效率更高;姓名长度不固定,用 VARCHAR 更合理,这一条如果报告里写出来,说明你理解数据类型的设计意图。DECIMAL(3,1)表示总长度 3 位、小数 1 位,学分 9.5 这样的值能存,但 10.5 就超出长度了,所以配合 CHECK 约束限制在 10 以内。ON DELETE CASCADE表示删除学生时自动删除其选课记录,这是外键约束的一种行为,实验里通常会单独出一道题问“删除选了课的学生会发生什么”,这里就提前埋好了答案。
建表顺序也有讲究:先建 student 和 course,再建 enroll。因为 enroll 有外键引用前两张表,如果顺序反了,MySQL 会报“无法创建表”的错误。实验报告的常见问题分析里经常要写这个错误,你把它写进报告,比单纯写“执行成功”有价值得多。索引最后建,是因为索引可以建在已有数据表上,不影响外键约束的创建顺序。
3.3 视图与常用查询:让实验报告里的“统计查询”更有说服力
建完表就该写查询实验了。这一部分最忌只贴一条SELECT * FROM student就交差。评分要求里的“高级查询”通常指以下几类:多表连接查询、聚合函数配合 GROUP BY、子查询、以及视图。下面这一段覆盖了这些点,而且每一条都是报告里能直接用的结果。
-- 查询每个学生的选课门数和平均成绩,按平均成绩降序 SELECT s.sno, s.sname, COUNT(e.cno) AS course_count, AVG(e.score) AS avg_score FROM student s LEFT JOIN enroll e ON s.sno = e.sno GROUP BY s.sno, s.sname ORDER BY avg_score DESC; -- 查询选了“数据库原理”但成绩低于 60 分的学生名单(子查询写法) SELECT sname FROM student WHERE sno IN ( SELECT e.sno FROM enroll e JOIN course c ON e.cno = c.cno WHERE c.cname = '数据库原理' AND e.score < 60 ); -- 创建视图:只暴露学生的基本信息和平均成绩,不暴露具体成绩单 CREATE VIEW v_student_avg AS SELECT s.sno, s.sname, s.major, ROUND(AVG(e.score), 2) AS avg_score FROM student s LEFT JOIN enroll e ON s.sno = e.sno GROUP BY s.sno, s.sname, s.major; -- 使用视图进行查询,展示“通过视图访问受控数据”的安全思路 SELECT * FROM v_student_avg WHERE avg_score >= 85;第一条查询里用了LEFT JOIN而不是INNER JOIN,是为了把没选课的学生也统计出来,选课门数为 0、平均成绩为 NULL。报告里写一句“用左外连接保证未选课学生不丢失”,就体现了你对连接类型的理解。第二条查询演示了子查询,逻辑上先查选课表得到低于 60 分的学号集合,再到学生表匹配姓名,这种写法比一次性 JOIN 更直观,适合在报告里做语句分析。第三条视图的关键是ROUND(AVG(e.score), 2),不保留小数会让结果显得不专业,保留两位更符合成绩统计习惯。视图创建后不要急着截图,先运行第四条查询,把输出结果截图放进实验报告,并注明“视图可以限制访问粒度,适合做权限控制演示”。
视图实验有个常见的坑,就是 MySQL 对视图的修改有限制,比如不能直接用 UPDATE 修改带有聚合函数的视图。这个限制可以写进报告的“实验结果分析”里,说明你为什么选择把视图用于查询而不是更新。一个报告里出现一次这样的思考,分数往往比多写十条 SELECT 更有效。
4. 实验报告这样写才像“做过了”:结构、截图与问题分析
SQL 写完了,最后一步是把过程落到实验报告里。这一步不少人不重视,觉得“代码跑完截图贴上就行”。但数据库概论实验报告的评分标准里,“实验过程记录”和“实验结果分析”通常占一半分数。报告写得好不好,本质上是在证明一件事:这个实验是你做的,而且你理解每一步在干什么。
4.1 一份实验报告的标准骨架和每部分字数
完整的数据库实验报告通常包含 6 个部分:实验目的、实验环境、实验内容与步骤、实验结果与分析、遇到的问题与解决、实验总结。一份 3000 字左右的实验报告里,我建议的篇幅分配是:实验目的 200 字,实验环境 150 字,实验内容与步骤 1200 字,实验结果与分析 800 字,遇到的问题与解决 400 字,实验总结 250 字。这个比例强调的是“过程”和“分析”,不是“代码清单”。
很多同学把实验内容与步骤写成了“我执行了以下 SQL:……”,然后贴一大段代码,没有一句解释。这等于把报告写成了操作手册而不是实验记录。更好的写法是分三步:先描述这个步骤要验证什么,然后给出核心 SQL 片段,最后写执行结果说明了什么。代码不要全贴,贴关键片段就够了,完整代码可以作为附录附在报告末尾。
实验目的别直接抄指导书。指导书写的是课程层面的目标,比如“掌握 SQL 语言”,你可以改成更具体的表述,比如“本实验通过设计学生选课数据库,验证外键约束对数据完整性的作用,并掌握多表查询中连接方法与统计函数的使用”。这种写法一眼就能看出你理解这个实验在练什么,而不是复制了指导书。
4.2 报表截图与运行结果:怎么证明你做的实验是真的
截图是实验报告里最容易出问题的地方。评分老师见过的假报告太多了,比如截图里只显示一条查询结果,没有任何上下文信息。一份可信的运行结果截图应该包含四个元素:数据库连接标识(localhost 或连接的库名)、执行的 SQL 语句、结果集的前几行、以及客户端窗口的标题栏或状态栏。只要截全,图就能证明“这是你在自己的环境里跑出来的”。如果结果集特别长,不要只截一张显示 6 行的图,建议分两次截:第一次截全览,第二次滚动到中间部分截细节。
还有两个小技巧值得用。第一,把客户端界面语言设置为中文或英文统一,别一半中文一半英文显得混乱。第二,命令行客户端里先执行SELECT DATABASE();再执行实验查询,这会让截图里多一行“当前数据库”,直接证明你用的是自己创建的库,而不是在随便一个测试库里跑的。我自己做实验时习惯把每张截图按“实验二_查询3_结果.png”这样命名,方便写报告时对号入座,省去来回找图的时间。
4.3 从“报错”到“问题分析”:把踩坑写进实验报告的技巧
“遇到的问题与解决”这一节是报告中最能体现含金量的部分。评分老师不怕你遇到问题,怕的是你遇到问题后直接绕过去。一个合格的“问题与解决”记录包含四个要素:报错原文(截图或精确复制)、问题发生场景(做哪一步时出现)、排查过程、最终解决方案。
举个例子,很多人建表时会遇到Cannot add foreign key constraint这个报错。在报告里你可以这样写:本实验在创建选课表时遇到该错误,检查发现两个表的外键字段类型不一致,学生表的学号是 CHAR(10),而选课表里误写成 VARCHAR(10),MySQL 要求外键关联的字段类型必须匹配,修改后成功建立外键。这段记录比写“改了下字段类型”要可信得多,因为你的排查过程完整表达出来了。
写这一节时注意一个分寸:别把文档写成“我遇到的问题全是环境问题”。如果所有问题都归因于安装配置,评分老师会觉得你的实验难度太低。应该主动包含几个数据库设计层面的问题,比如“查询结果出现重复行,改用 DISTINCT 去重”“删除学生记录时因外键约束失败,理解 ON DELETE 行为后调整策略”。这些问题才是数据库概论课真正想让你掌握的。多个真实的失败记录,比一个完美的成功记录更让人信服。
5. 数据库实验避坑指南:五个让报告翻车的细节点
这一章专门讲我见过的高频翻车点。每一条都是真实发生过的现象、原因和解决方式,做实验时可以直接对照排查。
5.1 中文乱码?先查字符集而不是查代码
现象:插入中文后用 SELECT 查询,结果显示为问号“???”或乱码字符。
原因:绝大多数情况是建库字符集不是 utf8mb4,或者客户端连接字符集与服务端不一致。有些同学的库是在图形界面工具里默认建的,默认字符集可能是 latin1。另一种可能是建表语句里单独指定了别的字符集,覆盖了库的默认设置。
解决:先执行SHOW CREATE DATABASE 库名;和SHOW CREATE TABLE 表名;查看字符集定义。如果库和表都是 utf8mb4,再检查连接设置,在连接成功后执行SET NAMES utf8mb4;。这是最快速的排查顺序,不要一开始就去改系统配置。我见过有人重装了三次 MySQL 才解决乱码,其实第一次查一下字符集就行。
5.2 数据库服务连不上:端口、服务名和授权三连查
现象:图形工具连接时报Can't connect to MySQL server on 'localhost'或Access denied for user。
原因:这类问题有三个源头,按概率排序。第一是 MySQL 服务没启动,常见于刚安装完还没执行net start;第二是端口被占用,3306 被其他程序抢占;第三是账号授权问题,比如用 root 远程连接时,root 没有开放对应主机的访问权限。
解决:按顺序排查。先执行net start | findstr mysql看服务是否存在,再用netstat -ano | findstr 3306看端口监听情况,最后登录检查权限表。如果确认服务正常、端口也没问题,那就是授权问题,执行一条授权语句给对应账号加上访问权限。顺序很重要,从服务层到网络层再到权限层,一层层缩小范围,别上来就重置密码。
5.3 事务实验结果反复无常?隔离级别没读对
现象:做事务实验时,两个会话同时操作同一批数据,有时候能看到未提交的数据,有时候看不到,结果与课本描述不一致。
原因:这是事务隔离级别在起作用。MySQL 8 默认的隔离级别是 REPEATABLE READ,不是课本上常见的 READ COMMITTED。在 REPEATABLE READ 下,同一个事务内多次读取结果保持一致,所以你在一个事务里看不到另一个事务未提交的修改,这容易被误读为“事务没生效”。
解决:在报告的实验分析里明确写出“当前会话的隔离级别”,并解释REPEATABLE READ与课本示例的差异。可以执行SELECT @@transaction_isolation;查看当前值,然后在报告里对比两个隔离级别下同样的操作会产生什么不同结果。这个分析本身就来自真实的实验观察,比抄课本定义有说服力得多。
5.4 视图里套视图:MySQL 的限制和课程评分习惯
现象:实验指导书里要求“基于视图创建视图”,执行时 MySQL 提示不支持,或者创建成功但查询时报错。
原因:MySQL 对视图有一些限制,比如创建视图时不能包含子查询里的某些语法,基于视图创建视图时要注意别触发算法限制。课本里演示的往往是 SQL Server 或其他数据库的语法,换到 MySQL 上不兼容就会出现这种情况。
解决:先确认实验题目是否指定了数据库产品。如果没有指定,可以在 MySQL 中创建基础视图和联合查询视图,用两种方式达到同样的查询效果,并在报告中说明 MySQL 与课堂演示数据库在视图实现上的差异。注意不要为了强行兼容而使用低版本的语法特性,把报告写成“我在 MySQL 上验证了视图的可用场景与限制”反而更诚实。
5.5 存储过程闪退:DELIMITER 和权限两个老坑
现象:在命令行客户端里定义存储过程,语句输入到一半直接报错退出,或者创建时报PROCEDURE ... does not exist。
原因:MySQL 命令行默认用分号作为语句结束符,而存储过程内部也有分号,于是客户端在错误的位置把语句截断了。这时候需要临时修改命令行的结束符。另外,创建存储过程需要CREATE ROUTINE权限,如果用的是权限受限的实验账号,会直接报权限不足。
解决:在定义存储过程前执行DELIMITER //,把所有内部语句用//结尾,结束后恢复DELIMITER ;。如果报权限错误,用管理员账号给实验账号授权,或者直接切换到 root 执行后截图说明权限要求。这两个坑在实验报告里写出来,能证明你真的做过存储过程实验,因为只抄代码的人不会遇到这两个问题。
6. 让实验报告经得起答辩追问:三个验证习惯与一条收尾检查
走到这一步,报告主体已经完成。最后一件事,是用半小时做一轮验证和收尾,确保报告里的结论经得起老师追问。三个验证习惯我每次都做。第一个是重新执行一遍报告中每一段关键 SQL,确认当前环境下还能跑通。不要用很早之前的截图,万一后来改动过表结构,截图和实际结果不一致,答辩时会被当场识破。第二个是检查外键和约束的实际效果,比如故意插入一条违反约束的数据,把报错结果截图放进报告的问题分析段,这比空口说“我建了外键”可信得多。第三个是用EXPLAIN分析一条查询的执行计划,确认索引是否真的被用上了。
-- 检查查询是否使用索引:type 列里出现 ref 或 const 表示索引生效 EXPLAIN SELECT * FROM enroll WHERE score > 90; -- 故意插入违反检查约束的数据,用于报告中的问题分析 INSERT INTO enroll VALUES ('20240001', 'C001', 120); -- 预期报错:Check constraint 'chk_score' is violatedEXPLAIN输出的type列和key列值得写进报告。如果type是ALL,说明是全表扫描,没有走索引;如果是ref或const,说明索引被有效使用。这一句话就能让实验报告从“会写 SQL”上升到“懂如何分析 SQL”。第二条故意报错的语句,我每次做实验都会留一个,因为评分标准里的“问题分析”部分需要真实的报错素材,现编的远不如实际执行留下记录。
最后一条收尾检查:通读一遍报告,确认每个“注意”“为什么”后面的解释都完整。好的数据库实验报告读起来像一篇技术博客,有清晰的逻辑链:需求是什么、我设计成什么样、遇到了什么问题、怎么解决的。如果某个模块只写了操作没有写理由,就补一句,哪怕只有一行。我自己的习惯是写完后放一天,第二天再读一遍,总能发现好几个逻辑断层。这种查漏比你多写十条 SQL 更值。希望这些方法能帮你在数据库概论的实验里少走点弯路,做出来的报告既能拿分,也真的对得起自己花的时间。
本文还有配套的精品资源,点击获取