
简介面向郑州大学计算机与人工智能学院《数据库系统原理》课程学习者及需要完成数据库实验的新手这份实验报告围绕万里数据库GreatSQL的部署与使用展开可用于对照实验流程、整理报告结构与复盘排错思路。压缩包内共1个docx文件大小约3.69MB内容以课程实验报告为主体便于直接查阅和二次整理。目前已有509人学习下载。报告覆盖DBMS系统认识、虚拟机CentOS环境配置、关闭SELinux与防火墙的原因及命令、依赖包安装、GreatSQL二进制包下载解压与服务管理并涉及基本表、视图、触发器、存储过程、约束等逻辑组件。对实验截图、图题表名、问题解决方法与结果分析也有规范示例适合作为课程实验参考、报告撰写模板和操作要点速查。1. 从九张实验单到一张知识地图数据库原理实验的全貌很多人对数据库原理实验的第一印象是敲 SQL把九个实验当成九道互不相干的练习题做完一个扔一个。真按顺序走一遍会发现它其实是一条单向递进的链路先把 DBMS 装起来并托管成服务再建库建表建索引然后用交互式 SQL 把数据取出来、改掉最后回头看清视图、触发器、存储过程这些逻辑组件以及数据页这个物理单位到底落在哪。实验报告是这条链路的存档每一张截图、每一条命令、每一段遇到的问题及更正都是在逼你复述自己的推导过程。把九个实验串成一条线而不是九条平行线复习时才有地方挂知识点这也是数据库原理这门课最容易在实验报告上拉开差距的地方。2. 环境落地从虚拟机到 systemd 托管的五步链路装数据库这件事本身不难难的是装完之后能复现。实验一给出的路径是虚拟机 Linux 二进制包 systemd 托管这套组合的每一步都在解决一个具体问题弄明白为什么这么选后面出问题时才有排查方向。2.1 为什么先备一台能回滚的虚拟机虚拟机方案的核心价值不是省钱是可回滚。数据库安装涉及改配置文件、建系统用户、改目录属主、注册服务一旦某一步改错最省事的处理不是修而是回到快照重来。习惯了图形化界面的人第一次进命令行会不适应这个不适应的成本要提前算进去可以装最小化系统后再补图形环境也可以强迫自己只用命令行因为后续实验里能用到的操作百分之九十都是命令。系统版本选 CentOS 7 或更高的原因很实际——依赖包的仓库还在、systemd 是默认的服务管理器、二进制包标注的 glibc 版本能对上。2.2 关闭 SELinux 与防火墙三条理由和一组命令这是整个实验里最容易被照抄命令、不问原因带过的一步。关 SELinux 的理由通常给三条强制访问控制会限制进程的文件读写和网络通信数据库恰好需要大量特权操作策略规则复杂调试成本远高于实验收益每次访问控制检查都带性能开销。关防火墙的理由同样三条数据库监听的端口如果没有被规则放行就无法通信虚拟机内部开发测试不需要额外的网络隔离流量过滤本身会带来负担。# 临时关闭当前会话立即生效重启后失效 setenforce 0 # 永久关闭把配置文件中以 SELINUX 开头的那一行整行替换 sed -i /^SELINUX/c SELINUXdisabled /etc/selinux/config # 关闭并禁用防火墙避免重启后又自动起来 systemctl stop firewalld systemctl disable firewalld需要说清的是setenforce 0和配置文件两条命令各管一段前者只改运行时状态后者改开机行为只做一条都会在重启后翻车。sed那条用c命令做整行替换比正则替换更稳因为原文件里可能是SELINUXenforcing也可能是SELINUXpermissive整行换掉不用关心原值。systemctl disable和stop是两件事前者管开机自启后者管当前进程实验里两条都写是有道理的。2.3 依赖包清单每个包在替谁干活那条长长的yum install不是随便堆的分组看就清楚了libaio-devel提供异步 IO 支持数据库刷盘大量依赖它numactl-devel、numactl-libs处理 NUMA 架构下的内存亲和jemalloc及-devel是内存分配器替换系统默认实现后在高并发下碎片更少openssl与openssl-devel支撑 SSL 连接和编译期头文件perl及perl-Data-Dumper、perl-Digest-MD5、perl-JSON、perl-Test-Simple是配套脚本工具的运行时net-tools提供传统的网络查看命令pkg-config用于编译期依赖探测。yum install -y pkg-config perl libaio-devel numactl-devel numactl-libs \ net-tools openssl openssl-devel jemalloc jemalloc-devel \ perl-Data-Dumper perl-Digest-MD5 python2 perl-JSON perl-Test-Simple少装libaio的典型症状是初始化阶段直接报异步 IO 相关的错误而不是装完才慢慢出问题所以这类依赖要在安装前一次装齐别等报错再补。2.4 解压、建用户、改属主顺序错了就白干二进制包安装的本质是解压即安装没有 make、没有 make install所有工作集中在目录规划上。包放到/usr/local下解压得到一个带版本号的目录数据目录单独规划在/var/lib/mysql日志目录在/var/log。cd /usr/local tar xf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz # 建专用系统用户不分配家目录不允许登录 shell groupadd mysql useradd -g mysql mysql -d /dev/null -s /sbin/nologin # 数据目录必须先建出来否则后面的 chown 找不到目标 mkdir -p /var/lib/mysql chown -R mysql:mysql /var/lib/mysql /var/log \ /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal-d /dev/null -s /sbin/nologin这两个参数的用意是把这个用户变成纯服务账号没有可登录的 shell也就没有被拿来当跳板的风险。chown的顺序问题很关键——目录不存在时chown直接报错而前面mkdir漏掉的话服务启动时会因为数据目录属主不对而拒绝初始化报错信息通常指向权限而不是目录缺失容易查偏。2.5 systemd 托管与四条验证命令把数据库注册成系统服务换来的是统一的生命周期管理start、stop、restart、status一套命令走到底不用记各种启动脚本路径。注册分两步先写服务文件再让 systemd 重新读一遍配置。# 服务文件放在 systemd 的系统单元目录下 vim /lib/systemd/system/greatsql.service # 写完必须重载否则 systemd 不认识这个新服务 systemctl daemon-reload systemctl start greatsql systemctl status greatsqldaemon-reload是新手最容易漏的一条漏了之后systemctl start会直接说找不到单元而服务文件明明躺在目录里。启动后的验证建议按四层走systemctl status看服务自身的状态和最近日志ps -ef | grep mysqld确认进程真的在跑而不是服务状态假活ss -lntp | grep mysqld确认端口已经监听ls /var/lib/mysql确认数据文件已经生成。四层里前两层看活没活后两层看通不通、有没有数据缺一层就可能出现服务显示正常但客户端连不上的情况。全局配置文件/etc/my.cnf也在这条链路上端口、数据目录、字符集这些都从这里读改完同样要restart才生效。3. 数据定义库、表、索引三件套的写法与顺序实验二到实验三的前半段全部围绕 DDL 展开。这部分语法不难难在结构设计的顺序感先有库才有表先有父表才有外键先有表才有索引顺序乱了报错信息往往指向语法而不是依赖关系。3.1 建库之后要确认的四件事建库只有一句CREATE DATABASE DB;但实验要求里那句察看数据库的存储位置、文件名称、对应的文件的个数、文件的大小才是重点。库建出来不是空的它对应磁盘上一个目录和一组文件这些信息决定了后面备份、迁移、扩容怎么做。CREATE DATABASE DB; SHOW DATABASES; USE DB; -- 查数据目录位置库目录就挂在它下面 SHOW VARIABLES LIKE datadir;datadir给出的是根目录库名对应的子目录就在里面文件个数和大小用目录列表看更直观。这一组查询的意义在于建立逻辑库 ↔ 物理目录的映射意识后面做索引、看数据页、算表空间都建立在同一个认知上。3.2 六张表的结构与建表顺序整个实验的数据模型可以归成六张表院系、教师、学生、课程、选课、授课。前四张是实体表SC和Teaches是联系表。字符类型的选择上学号、课程号这类定长编码用char姓名、专业名这类长度不一的用char或varchar都行实验里统一用char是为了对齐教材示例。CREATE TABLE Students( Sno char(12) PRIMARY KEY, Sname char(20) NOT NULL, Sex char(4) CHECK (Sex IN (男,女)), Birthday DATE, Speciality char(20), Dno char(4) ); CREATE TABLE Courses( Cno char(5) PRIMARY KEY, Cname char(30) NOT NULL, Period SMALLINT, Credit SMALLINT ); -- 联系表复合主键保证同一个学生对同一门课只有一条成绩 CREATE TABLE SC( Sno char(12), Cno char(5), Grade int CHECK (Grade 0 AND Grade 100), PRIMARY KEY (Sno, Cno) );外键没有写进CREATE TABLE而是建完表之后用ALTER TABLE ... ADD FOREIGN KEY补上这个做法不是偷懒。建表时写外键要求被引用表已经存在六张表互相引用时很难排出一个人人满意的顺序拆成先建全部表、再加全部外键两步依赖关系就统一推迟到最后出错时也只看一条语句。3.3 约束主键、外键、唯一、非空与 CHECK约束是 DDL 里最有考试价值的部分因为它直接对应数据完整性这一章。主键约束保证实体完整性一个表只能有一个可以是单列也可以是复合列外键约束保证参照完整性插入子表记录时父表必须有对应记录删除父表记录时要看有没有级联规则非空约束管住必须填的列唯一约束允许一个空值但值不能重复CHECK 约束写的是列级或表级的布尔条件。实验里Grade上的CHECK (Grade 0 AND Grade 100)是个好例子它把成绩必须在 0 到 100 之间这条业务规则下沉到了表结构里。需要注意的是 CHECK 的实际执行力度跟版本和引擎有关写进报告时最好实测一条越界插入用报错信息说话而不是想当然地认为它一定拦截。3.4 索引普通、唯一与复合主键的最左前缀索引实验只有两条建、一条删但背后的选择题不少。-- 普通索引加速按院系号过滤 CREATE INDEX Student_Dept ON Students(Dno); -- 唯一索引既加速又约束课程号不重复 CREATE UNIQUE INDEX Course_Cno ON Courses(Cno); -- 删除索引要带 ON 指明表 DROP INDEX Course_Cno ON Courses;SC表上的主键(Sno, Cno)本身就是一个复合索引这个顺序决定了它能服务哪些查询按Sno查、按Sno Cno查都能用上单独按Cno查就用不上这就是最左前缀。复习时如果只记住主键会建索引遇到为什么这条查询没走索引的题就会卡住。同理DROP INDEX后面必须跟ON 表名这一点和某些数据库的写法不同属于容易在实验报告里被扣分的细节。3.5 删表删索引CASCADE 与 ON 子句实验里出现过drop table students cascade这种写法用意是先清掉表上挂着的引用关系再删表。实际执行时要注意两点一是删表顺序仍然受外键约束被引用的父表要后删或者先解除引用二是CASCADE这类关键字在不同数据库上的支持程度不一致写进报告前要实测。相比之下删索引简单得多DROP INDEX 索引名 ON 表名一句到位删完用SHOW INDEX FROM 表名确认即可。4. 交互式 SQL查询与更新的四条主线实验三对应教材的查询与更新两大块表面上是把书上例子敲一遍实际上可以归成四条主线怎么选列、怎么筛行、怎么连表算、怎么改数据。每条主线都有自己的边界情况考试和实验报告里失分基本都落在这里。4.1 投影与表达式列不带 WHERE 的查询也有讲究最简单的SELECT * FROM Courses;考的是取全部列全部行但真正有信息量的是表达式列-- 用当前年份减出生年份得到年龄别名让结果列可读 SELECT Sname, 2024 - YEAR(Birthday) AS Age FROM Students;这里有两个点值得记YEAR()是函数调用返回整数参与算术运算没问题别名AS Age不只是好看某些客户端会把表达式列显示成一大串别名能让报告里的截图更清楚。更关键的是WHERE子句里对列使用函数会导致该列上的索引失效这条在性能章节是重点在实验阶段先把函数作用在列上这个动作标出来后面复习时才有钩子。4.2 WHERE 子句的三类边界比较、BETWEEN、IN筛选条件看起来花样很多归归类就三类单值比较、区间判断、集合判断。-- 等值筛选 SELECT Tname, Sex FROM Teachers WHERE Title 讲师; -- 去重同一个学生多门不及格只出现一次 SELECT DISTINCT Sno FROM SC WHERE Grade 60; -- 区间闭区间两端都包含 SELECT Sname, Speciality FROM Students WHERE YEAR(Birthday) BETWEEN 1997 AND 1999; -- 集合并取反 SELECT Sno, Sname FROM Students WHERE Speciality IN (计算机,软件工程); SELECT Sno, Sname FROM Students WHERE Speciality NOT IN (计算机,软件工程);BETWEEN是闭区间这一点必须记牢写报告时最好用边界值实测一次。IN与NOT IN的差别在心智上很小在结果上可能极大如果子查询或列表里混进了NULLNOT IN会整体返回空集因为x NOT IN (..., NULL)的真值永远是未知。这个坑在实验阶段不一定踩得到但在考试和实际项目里是高频翻车点。4.3 连接与聚合把 SC 表用起来单表查询练熟之后真正的分水岭是连接和聚合。教材的查询实例覆盖了各类连接落到这套六表模型上最典型的是每个学生的平均分-- 学生表连接选课表按学生分组求平均分再筛掉低分 SELECT s.Sno, s.Sname, ROUND(AVG(sc.Grade), 1) AS avg_grade FROM Students s JOIN SC sc ON s.Sno sc.Sno GROUP BY s.Sno, s.Sname HAVING AVG(sc.Grade) 85;这段里每个关键字都有考点JOIN ... ON决定连接条件写错就变成笛卡尔积GROUP BY后面要带上所有非聚合的输出列虽然某些模式允许省略但结果不确定HAVING和WHERE的分工是先筛行还是先筛组把聚合条件写进WHERE会直接报错。写实验报告时把改一个条件、结果怎么变记录下来比贴一张正确结果的截图有价值得多。4.4 更新操作INSERT、UPDATE、DELETE 的约束联动更新操作最容易被低估因为它语法短但每一条都在和约束打交道。-- 多行插入一次提交比逐条快也便于对照结果 INSERT INTO SC (Sno, Cno, Grade) VALUES (201705001,cs301,92), (201705002,cs301,88); -- 带条件的更新WHERE 漏写就是全表改 UPDATE SC SET Grade Grade 5 WHERE Sno 201705003 AND Cno cs101; -- 删除空值成绩 DELETE FROM SC WHERE Grade IS NULL;插入时首先撞上的是外键往SC里插一条学号不存在的记录会被拒绝这正好验证参照完整性。更新时撞上的是CHECK把成绩改成 120 会被拦下。删除时撞上的是级联规则删父表记录前先看子表有没有引用。这三条如果只在报告里写操作成功等于什么都没验证写清故意制造一次失败、看到什么报错才是这份报告真正的技术含量。4.5 标准 SQL 与 GreatSQL 的差异点实验要求里专门提了一句注意标准 SQL 和相应数据库语句的相同与不同之处这个提示值得展开。相同的是主体语法SELECT、INSERT、UPDATE、DELETE、JOIN、GROUP BY这些在标准里都有定义写出来基本通用。不同的是方言层分页写法、日期函数、字符串拼接、自增列定义、LIMIT的位置、反引号的使用各家都不一样。复习时不需要背全只需要记住哪些地方我依赖了方言写进报告时标注一句换数据库时才不会措手不及。5. 易漏点排查视图、触发器、存储过程与数据页的五个盲区实验一的后半段要求了解数据库的逻辑组件和物理组件这部分内容概念多、操作少最容易变成抄一段定义交差。真正梳理下来会发现这里的失分点集中在用错命令去查对象和把逻辑单位当成物理单位两类。5.1 逻辑组件的五个对象各自管什么基本表是实际存储数据的表是数据的落点。视图是基于一张或多张表的查询结果动态生成的虚表本身不存数据价值在于简化复杂查询和限制行列访问。触发器绑定在表的增删改事件上事件发生即自动执行用来维护一致性和实现业务规则。存储过程是一组预编译的 SQL 语句集合一次调用执行一批操作减少网络往返。约束是施加在数据上的规则主键、外键、唯一、非空、CHECK 都属于这一类。这五者的关系可以这样记基本表和视图面向读触发器和存储过程面向动作约束面向不许做什么。查它们的元数据各有各的位置写实验报告时把每个对象对应到一张系统表比抄定义有用得多。-- 视图元数据在 VIEWS 里 SELECT * FROM information_schema.VIEWS; -- 触发器元数据在 TRIGGERS 里 SELECT * FROM information_schema.TRIGGERS; -- 存储过程ROUTINES 里混着函数要按类型过滤 SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_TYPE PROCEDURE; -- 约束从 KEY_COLUMN_USAGE 看键的使用情况 SELECT * FROM information_schema.KEY_COLUMN_USAGE;5.2 物理组件的分层与数据页物理层面可以按连接进来之后数据怎么走来记连接池组件负责连接复用系统管理和控制工具负责实例级运维SQL 接口接收语句查询解析器做语法语义分析查询优化器生成执行计划可插拔存储引擎负责真正的读写系统与日志文件兜底持久化。这条链路的价值在于定位问题语法错误停在解析器慢查询停在优化器或引擎文件损坏落在日志和存储文件上。存储单位这一问最容易答错。数据库物理存储的基本单位是数据页不是行、不是表。行是逻辑单位页是磁盘和内存之间交换的单位表是逻辑容器表空间是文件的组织方式。以常见的 InnoDB 引擎为例一个页默认 16KB一页里放多行索引和数据都按页组织读一行实际是读一页进内存。实验里ls /var/lib/mysql看到的那些文件背后就是按页组织的数据。把这层关系讲清楚比背存储单位是页这五个字更抗考。5.3 五条最容易漏的细节易漏点一查视图用了看连接的语句。为什么漏视图、进程、会话这几个概念在中文里都带视或表容易混。怎么补查视图对象一律走information_schema.VIEWSSHOW FULL PROCESSLIST看的是当前连接线程两者完全不搭界写报告前把命令和对象对一遍。易漏点二查存储过程忘了类型过滤。为什么漏ROUTINES里同时存函数和过程不过滤就会多出一堆函数。怎么补固定加上WHERE ROUTINE_TYPE PROCEDURE并顺带记住函数对应FUNCTION。易漏点三把行当成物理存储单位。为什么漏平时写 SQL 都是按行思考物理层很少接触。怎么补记住内存与磁盘之间以页为单位交换这句话答题时先答页再答大小别把逻辑单位和物理单位混着说。易漏点四报告排版规则记反。为什么漏截图、图题、表名这些格式要求在实验要求里写得很细但做实验时只想着跑通命令。怎么补图题在图下方、表名在表上方、图表都要编号、正文段首空两格这四条在交稿前过一遍成本极低扣分收益极高。易漏点五命令里的标点与符号。为什么漏复制粘贴和输入法切换是两大元凶。怎么补权限相关的setenforce 0是空格分隔写成等号赋值会报错SQL 里的逗号、引号必须是英文半角中文逗号会让建表语句直接语法错误日期字面量用短横线分隔写成下划线虽然在宽松模式下可能被接受但跨版本就不保证。这三类错误不会给你任何提示只给一行报错位置养成报错先看光标附近有没有中文符号的习惯能省很多时间。5.4 顺带记住的一层这套发行版在引擎层做了什么物理组件之外实验材料里还列了一组引擎层增强复习时可以作为了解级别的知识点记考到就答考不到也不亏。特性解决的问题记忆点组复制增强多机房数据同步、流控抖动地理标签、大事务检测并行查询OLAP 与周期性统计慢分析型场景收益明显事务锁结构优化高并发下锁竞争红黑树改无锁哈希仲裁节点降成本又保可用不存全量数据也能参与决策单主选主机制主库切换慢选主更快更稳新流控机制复制组频繁抖动让复制跑得更平滑这张表的用法不是背名词而是建立数据库不只是存数据还有复制、并发、优化三条工程线的印象。做实验时只接触单机容易以为数据库就是一个mysqld进程加一堆表实际生产里复制和高可用占了很大篇幅。6. 复习清单九个实验压成一张自测表到复习阶段最有效的做法不是重读实验报告而是拿一张表自测每个实验只问自己一个问题答不上来就回去补那一块。下面这张表是我自己用的版本左列是实验编号中列是一个动作右列是一个必须能当场答出来的问题。实验核心动作自测问题一装 DBMS、注册服务不重载 systemd 直接 start 会报什么错二建库、建表、建索引为什么外键要建完表再加三交互式查询与更新NOT IN遇到 NULL 为什么返回空集四视图与触发器视图的元数据去哪张系统表查五存储过程与函数ROUTINES里怎么区分过程和函数六约束与完整性主键、唯一、非空三者的边界差在哪七索引与执行计划复合索引最左前缀失效的典型写法八备份与恢复逻辑备份和物理备份各适合什么场景九综合设计给你一个业务描述能不能画出六张表配套还有一张命令—对象对照清单考前十分钟扫一遍就够SHOW DATABASES看库、SHOW TABLES看表、SHOW INDEX FROM 表看索引、information_schema.VIEWS看视图、TRIGGERS看触发器、ROUTINES看过程与函数、KEY_COLUMN_USAGE看约束、SHOW VARIABLES LIKE datadir看物理落点。这八条能覆盖实验一和实验二里绝大多数了解类考点剩下的是 SQL 手写能力只能靠敲。真正要花时间的是第三块把每条 DDL 和 DML 都跑一遍失败路径。故意插一条外键不存在的记录、故意把成绩改成 120、故意在WHERE里漏条件再回滚、故意把英文逗号换成中文逗号看报错长什么样。这些失败信息在考试里不会考但在实验报告的遇到的问题及更正一栏里是硬通货而且它们能让你对约束的印象从知道有变成见过它拦人。最后说个我自己的教训。第一次做这类实验时我把九份报告当成九个独立作业每份都从零开始配环境、建库、敲 SQL交上去看着挺完整一到期末复习发现脑子里是散的知道怎么建索引但说不清索引和主键的关系知道视图不存数据但说不出它存在哪张系统表。后来我改成先把整条链路默写一遍——从关 SELinux 到systemctl status从CREATE DATABASE到information_schema查询——写不出来的地方就是漏洞再回去补那一节。从那以后我每次做带环境的实验都强制先画一张命令 → 对象 → 验证方式的三列表再动手敲。希望帮到你。本文还有配套的精品资源点击获取