数据库原理实验从GreatSQL环境部署到SQL实操的完整避坑指南
简介郑州大学计算机与人工智能学院《数据库系统原理》课程的实验报告资源适合正在学习数据库原理、需要完成同类实验的学生参考。内容涵盖认识DBMS系统、万里数据库GreatSQL的安装与配置、基本表/视图/触发器/存储过程等逻辑组件操作以及实验报告撰写规范完整记录了关闭SELinux与防火墙、安装依赖包、解压部署、启动服务等关键步骤并配有结果截图说明与过程分析。资源为1个docx文档压缩包约3.69MB结构清晰便于直接借鉴。目前已累计509人学习能够帮助读者快速掌握GreatSQL环境搭建方法规范撰写实验报告并解决安装配置中常见的权限、端口和依赖问题适合数据库课程实验备查与技能提升。1. 为什么数据库原理实验要从“装好一个DBMS”开始数据库原理实验报告这件事多数人以为难点在SQL语句真正动手才发现最容易被卡住的反而是第一步把DBMS装好并跑起来。一套常见的实验环境是这样搭的虚拟机里跑CentOS用二进制包部署GreatSQL 8.0.32。相比Windows一键安装这种方式多绕几步却能逼着你把目录结构、系统服务、配置文件这些平时看不见的东西一次摸清楚。这篇文章围绕一条完整可复现的实验链路展开环境配置与部署、建库建表和索引、交互式SQL验证、报告排版与验收答辩。适合正在按“认识DBMS—建库建表—SQL操作”这条主线完成数据库原理实验的同学也适合想快速把GreatSQL基础环境搭起来、理解数据页与逻辑组件关系的开发者。2. 环境准备与部署关闭SELinux和防火墙后用二进制包装好GreatSQL2.1 为什么选“虚拟机CentOS二进制包”而不是一键安装选型这一步不是随便定的后面所有实验都依赖这个环境选错了后面全是坑。第一用VMware跑虚拟机是为了隔离。实验过程里要改系统安全策略、反复启动停止数据库服务装在物理机上出了问题会影响日常使用虚拟机里随便折腾出问题还可以用快照当后悔药。第二选CentOS 7以上而不是带图形界面的系统是为了强迫自己用命令行和systemd管理服务这套操作习惯跟生产环境一致。第三也是最重要的一点用二进制包而不是yum install是因为yum自动装好后程序文件分散在/usr/bin、/var/lib、/etc这些目录里你根本看不清一个数据库管理系统由哪些部分组成二进制包解压后所有组件集中在一个目录下bin、lib、share一目了然正好对应实验中“认识DBMS系统构架”这个目标。2.2 关闭SELinux和防火墙安全策略与数据库运行的取舍新装好的CentOS上第一件事不是装数据库而是先处理SELinux和防火墙这一点很多同学不理解。SELinux是强制访问控制MAC机制它会限制mysqld进程的文件读写和网络通信权限。数据库启动时要执行大量特权操作被SELinux拦下后日志里的报错很玄学——看起来是权限问题但文件属主和权限明明都是对的。另外SELinux的配置策略复杂学习和排查成本高它对每个进程做访问控制检查还会造成一定的性能开销。防火墙的逻辑类似数据库监听3306端口默认防火墙策略会挡掉外部连接关闭后能避免端口阻塞也简化了虚拟机的网络配置。这套取舍在答辩时经常被追问理由是站得住的。# 临时关闭SELinux立即生效 setenforce0 # 持久化关闭把配置文件里的SELINUX改为disabled重启后仍然生效 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/config # 关闭防火墙并禁用开机自启 systemctl stop firewalld systemctl disable firewalld # 验证当前状态输出Disabled说明已关闭 getenforce注意setenforce0只对当前运行周期生效重启后系统会重新读取配置文件所以临时和持久化两条命令都要执行。很多同学只跑了第一条虚拟机一重启又变回Enforcing这就是后面要讲的经典翻车点。2.3 部署实操依赖包、解压、系统用户、systemd与启动验证依赖包看起来一长串实际分成几类libaio-devel是异步IO库InnoDB写数据时要依赖它numactl系列用于NUMA架构下绑定CPU和内存mysqld启动时会检测jemalloc是高性能内存分配器用来减少内存碎片其余perl相关包是数据库初始化脚本的运行依赖。被问到“为什么装这么多包”时能讲清libaio、numactl、jemalloc这三个就足够说明你真的理解了。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依赖装完后把下载好的二进制包放到/usr/local目录下解压然后创建专用的mysql系统用户。用/sbin/nologin作为登录shell意思是这个账户只用来跑服务不允许登录系统属于标准的服务账户做法。cd /usr/local tar xf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz /sbin/groupadd mysql /sbin/useradd -g mysql mysql -d /dev/null -s /sbin/nologin mkdir -p /var/lib/mysql chown -R mysql:mysql /var/lib/mysql /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal接下来编辑systemd服务文件把GreatSQL注册成系统服务。服务文件里最核心的是ExecStart路径必须和实际解压目录完全一致很多启动失败都出在这一行。[Unit] DescriptionGreatSQL Server Afternetwork.target [Service] Usermysql Groupmysql ExecStart/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/bin/mysqld --defaults-file/etc/my.cnf Restarton-failure [Install] WantedBymulti-user.target然后编辑全局配置文件/etc/my.cnf这里决定了数据库的数据文件放哪、监听哪个端口、日志写到哪里。datadir对应的就是物理存储位置后面查看数据库文件时都要回到这个目录。[mysqld] usermysql basedir/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal datadir/var/lib/mysql socket/tmp/mysql.sock port3306 pid-file/var/lib/mysql/mysqld.pid log-error/var/log/mysql/error.log character-set-serverutf8mb4启动验证分三步走。先systemctl daemon-reload让新的服务文件生效再systemctl start greatsql启动最后systemctl status greatsql确认状态。进程级别还要用ps -ef | grep mysqld确认mysqld进程存在ss -lntp | grep mysqld确认3306端口正常监听ls /var/lib/mysql查看初始化出来的数据文件。如果启动失败第一件事就是去看log-error指向的错误日志不要瞎猜。提示我这套流程里所有命令都是在root用户下执行的如果你用普通用户加sudo注意chown那一步的属主依然是mysql别顺手把安装目录改成自己的用户名。3. 数据库设计实验从逻辑组件到索引的建库建表实务3.1 认识DBMS逻辑组件与物理存储基本表、视图、触发器、存储过程、约束实验一要求了解数据库系统的逻辑组件和物理组件这部分不是背概念而是要能在GreatSQL里把这些组件找出来。逻辑组件里基本表是实际存储数据的表SHOW TABLES可以直接看到视图是虚拟表基于一个或多个基本表的查询结果动态生成不实际存储数据触发器是特殊类型的存储过程在插入、更新、删除事件发生时自动执行常用于维护数据一致性和业务规则存储过程是预编译的SQL语句集合封装后可以反复调用约束是对数据的限制规则主要包括主键、外键、唯一和非空。information_schema是MySQL体系里的元数据库专门存这些组件的信息实验报告里常用的查看命令有这么几条。表1逻辑组件与information_schema查看命令对照组件作用查看命令基本表实际存储数据的表SHOW TABLES;视图基于查询结果的虚拟表SHOW FULL PROCESSLIST;触发器事件发生时自动执行SELECT * FROM information_schema.TRIGGERS;存储过程预编译SQL单元SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_TYPEPROCEDURE;约束数据完整性规则SELECT * FROM information_schema.KEY_COLUMN_USAGE;物理组件方面GreatSQL的组成包括连接池组件、系统管理和控制工具、SQL接口组件、查询解析器、查询优化器、可插拔存储引擎以及系统与日志文件。物理存储的存储单位是数据页InnoDB默认页大小16KB数据以页为单位在磁盘上存放最终体现为文件。确定数据存放位置的方法就是查看my.cnf里的datadir配置这个我们在部署阶段已经配过了。3.2 建库建表主键、非空约束与复合主键的设计取舍实验二从创建数据库开始这一步很简单但后面的表都挂在它下面。CREATE DATABASE DB; SHOW DATABASES; USE DB;建表是实验二的核心。教材要求建STUDENTS、COURSES、SC三张表注意第一次建表时只用了id和name两个字段做练习真正落地的正式表结构必须带上完整属性。CREATE TABLE STUDENTS ( Sno char(9) PRIMARY KEY, Sname char(10) NOT NULL, Sex char(2), Birthday DATE, Speciality char(20), Dno char(4) ); CREATE TABLE COURSES ( Cno char(5) PRIMARY KEY, Cname char(20) NOT NULL, Period int, Credit int ); CREATE TABLE SC ( Sno char(9), Cno char(5), Grade int, PRIMARY KEY (Sno, Cno) );这里几个设计点要能解释清楚。Sno用char(9)定长字符串因为学号长度固定定长类型比varchar省存储开销Sname加NOT NULL不允许一条没有姓名的学生记录存在这是非空约束的实际意义SC表用(Sno, Cno)复合主键因为一个学生选一门课只产生一条成绩记录(Sno, Cno)这个组合才能唯一标识一行单独拿Sno或Cno都不唯一。这个复合主键的设计在答辩时几乎必问核心答法就是“语义上的唯一性由组合决定”。插入几条测试数据用于后续查询验证。INSERT INTO STUDENTS VALUES (201705001, 张华, 男, 1999-12-16, 计算机, CS), (201705002, 张晓霞, 女, 1999-01-01, 软件工程, SE), (201706001, 李玉, 女, 1999-10-17, 数学, MA);删除表时有个容易忽略的问题。STUDENTS、COURSES被SC的外键引用直接删父表会报外键约束错误所以要么先删SC再删父表要么用DROP TABLE students CASCADE。实验环境里用CASCADE省事但生产环境不建议这么做正式库删表前一定要先备份。3.3 索引设计普通索引与唯一索引的创建、删除和验证索引是数据库性能的关键实验二要求用SQL语句创建和删除索引。最典型的案例是在Students表的Dno列上建普通索引在Courses表的Cno列上建唯一索引。CREATE INDEX Student_Dept ON Students (Dno); CREATE UNIQUE INDEX Course_Cno ON Courses (Cno); SHOW INDEX FROM Students; DROP INDEX Course_Cno ON Courses;设计上要注意区别Dno是经常作为查询条件的列按院系查学生是很典型的检索场景普通B树索引能加速这类查询而Course_Cno建的是唯一索引语义是保证Cno列的取值不重复。主键本身会自动创建聚簇索引所以Cno上其实已经不缺唯一性再做一次唯一索引更多是为了验证“主键约束”和“唯一索引”是两个层面的概念——一个是约束一个是索引结构。实验报告里建议把SHOW INDEX的输出截图留存用来说明索引创建前后查询计划的差别后面的交互式SQL实验会用到。注意在生产环境的真实业务表里已经有主键的列通常不需要再单独建唯一索引这里建只是为了实验验证别把习惯带到真实项目里。4. 交互式SQL实验六张表上完整跑通教材查询与更新案例4.1 实验数据准备六张表结构与外键关系实验三要覆盖教材里的查询和更新案例原来的三张表不够用需要扩展成六张表Departments、Teachers、Students、Courses、SC、Teaches。这六张表构成了一个简化版的教学管理系统外键关系比实验二复杂得多。建表SQL可以直接复用但要注意执行顺序——先建不依赖其他表的Departments和Courses再建引用它们的Teachers、Students最后建SC和Teaches。CREATE TABLE Departments ( Dno char(4) PRIMARY KEY, Dname char(20), Dheadno char(7) ); CREATE TABLE Teachers ( Tno char(7) PRIMARY KEY, Tname char(10) NOT NULL, Sex char(2) CHECK (Sex 男 OR Sex 女), Birthday DATE, Title char(10), Dno char(4) ); CREATE TABLE Students ( Sno char(12) PRIMARY KEY, Sname char(20) NOT NULL, Birthday DATE, Speciality char(20), Dno char(4), Sex 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), FOREIGN KEY (Sno) REFERENCES Students (Sno), FOREIGN KEY (Cno) REFERENCES Courses (Cno) ); CREATE TABLE Teaches ( Tno char(7), Cno char(5), TCsores int, PRIMARY KEY (Tno, Cno) );外键关系没有在建表时全部写完后续用ALTER TABLE补上。这是初学阶段比较友好的做法建表时先把结构定清楚再逐个添加外键能更直观地理解FOREIGN KEY语法和引用关系。ALTER TABLE teaches ADD FOREIGN KEY (Cno) REFERENCES Courses (Cno); ALTER TABLE teaches ADD FOREIGN KEY (Tno) REFERENCES teachers (Tno); ALTER TABLE students ADD FOREIGN KEY (Dno) REFERENCES departments (Dno); ALTER TABLE teachers ADD FOREIGN KEY (Dno) REFERENCES departments (Dno);插入数据的顺序也受外键约束影响必须先插父表再插子表。顺序反了会直接报“外键约束失败”这不是SQL写错而是数据依赖顺序的问题。先插departments和courses然后teachers和students最后SC和teaches每张表插完后用SELECT COUNT(*)验证行数。4.2 查询语句的分类验证从全表查询到条件、范围与集合匹配查询是实验三的重头戏要按类型分类跑每一类都要截图留痕。第一类是不带WHERE的全表查询比如SELECT * FROM Courses用来确认数据完整写入带计算列的查询也很典型比如用YEAR函数从Birthday计算年龄这属于表达式查询。-- 全表查询 SELECT * FROM Courses; -- 计算列查询直接算年龄 SELECT Sname, 2024 - YEAR(Birthday) AS Age FROM Students; -- 带WHERE的等值比较 SELECT Tname, Sex FROM Teachers WHERE Title 讲师; -- 去重查询不及格学生的学号DISTINCT去掉重复 SELECT DISTINCT Sno FROM SC WHERE Grade 60;第二类是范围查询BETWEEN和NOT BETWEEN是一对注意BETWEEN是闭区间包含边界值。-- 查询1997到1999年出生的学生 SELECT Sname, Speciality FROM Students WHERE YEAR(Birthday) BETWEEN 1997 AND 1999; -- NOT BETWEEN是互补范围 SELECT Sname, Speciality FROM Students WHERE YEAR(Birthday) NOT BETWEEN 1997 AND 1999;第三类是集合匹配IN和NOT IN。IN的语义是“属于这个集合”注意集合里的字符串也要用单引号。SELECT Sno, Sname FROM Students WHERE Speciality IN (计算机, 软件工程); SELECT Sno, Sname FROM Students WHERE Speciality NOT IN (计算机, 软件工程);通常教材这一步还会补一条模糊匹配LIKE和一条排序查询虽然不是所有同学都会跑到但实验报告里多覆盖一类查询验收时内容更完整。-- 模糊匹配姓张的学生 SELECT Sname, Sno FROM Students WHERE Sname LIKE 张%; -- 排序成绩从高到低 SELECT Sno, Cno, Grade FROM SC ORDER BY Grade DESC;执行每一条查询后都要观察结果集是否符合预期。比如DISTINCT那条如果SC表里同一个学号有多条不及格记录去重后只保留一个LIKE 张%只能匹配姓张开头的记录%张匹配结尾是张的记录。实验结果分析就要写这些观察不能让截图自己说话。4.3 更新操作与标准SQL的差异插入、修改、删除的边界条件更新操作分插入、修改、删除三类。插入就是给现有表补充行注意外键约束和CHECK约束都会在这里生效Grade超过100直接报错。修改数据最怕的一件事是UPDATE不带WHERE整张表的成绩全被改掉这在真实业务里是事故级别的问题。我一般会先写SELECT把要改的行查出来确认再执行UPDATE养成“先查后改”的习惯。-- 安全更新示范先查再改 SELECT * FROM SC WHERE Sno 201705001 AND Cno cs101; UPDATE SC SET Grade 90 WHERE Sno 201705001 AND Cno cs101;DELETE的边界条件在外键上。被其他表引用的行不能直接删比如删掉departments里还挂着教师的系外键约束会拦下来。正确做法是先处理子表数据或者用事务包裹确认没问题再COMMIT。事务在GreatSQL里跟标准SQL有一个明显差异GreatSQL基于MySQL 8.0默认隔离级别是Repeatable Read而标准SQL默认是Read Committed另外UPDATE和DELETE支持LIMIT扩展这是MySQL系的特有语法。实验报告里可以单独写一段“标准SQL与GreatSQL差异”的对比这类内容在评分时很加分。提示做更新类实验前一定要确认当前会话没有开启自动提交以外的隐式事务或者干脆主动用BEGIN开启事务操作完验证结果再COMMIT。这样就算手误也能回滚等于给自己留了后悔药。5. 实验报告避坑指南安装启动、SQL执行与截图排版的五个翻车点5.1 systemctl启动失败目录属主与systemd路径不一致现象systemctl start greatsql执行后服务状态一直是activating或failedps查不到mysqld进程。原因八成是解压后的安装目录属主不是mysqlmysqld没有权限写日志和临时文件或者systemd服务文件里ExecStart的路径跟实际解压目录不一致。解决执行chown -R mysql:mysql把安装目录和/var/lib/mysql全部授权然后逐字核对greatsql.service里的路径最后看log-error指向的日志文件里面的报错信息会直接告诉你是权限问题还是路径问题。5.2 SELinux改完重启又恢复临时与持久化配置分不清现象刚执行完setenforce0getenforce显示Disabled但虚拟机一重启又变回Enforcing。原因setenforce0只是临时修改当前运行状态没有写入配置文件重启后系统读到的还是/etc/selinux/config里的enforcing。解决必须修改/etc/selinux/config把SELINUXenforcing改成SELINUXdisabled然后重启或用setenforce0配合生效。用getenforce验证一次确认输出是Disabled才算彻底关掉。这条我见过太多同学踩几乎每届都有。5.3 中文引号导致SQL报错全角字符与字符集问题现象执行WHERE Title讲师时报语法错误或者插入的中文数据在查询结果里显示成乱码。原因SQL字符串常量里混入了中文全角引号“ ”或‘ ’数据库解析器不认全角字符另一种情况是表或库的字符集不是utf8系列中文落盘后编码不对。解决所有SQL里的字符串常量一律用英文半角单引号写完后可以用编辑器开启“显示全角字符”高亮检查建表时显式指定DEFAULT CHARSETutf8mb4前面my.cnf里也加了character-set-serverutf8mb4双保险。5.4 外键约束下的删除顺序父表子表分不清现象DROP TABLE Departments直接执行失败报错提示外键约束阻止了删除。原因Students和Teachers都通过Dno引用Departments父表还存在被引用关系时数据库不允许直接删除父表。初学时很容易忽略“先删子表再删父表”的顺序。解决先DROP引用它的子表再用DROP TABLE departments或者用DROP TABLE departments CASCADE强制级联删除但实验报告里建议把两种方式都写出来解释清楚CASCADE的代价是连带删掉所有引用数据。5.5 截图不规范导致报告被退回图题、表题、排版缺一不可现象电子版报告里只有一张张截图截图的图题、编号都没有表格也没有名字提交后被退回重改。原因实验报告要求里明确写了“截图下方需有图的编号和图题表格上方有编号及表名”但对只关注SQL本身的同学来说这排要求最容易漏。解决每做完一步立刻截图并在截图下方标注“图1 创建数据库”“图2 创建基本表”这类编号和标题表格上方写“表1 Students表结构”加表名。可以把截图命名规则统一成“实验序号_图序号_内容”最后排版时按顺序插入正文里用编号引用。段首空两个字、行文用书面语这些都是默认要求别在这上面丢分。6. 验收与答辩一份能直接拿到成绩的实验报告怎么交6.1 验收清单按检查项逐条过写报告前先按验收清单跑一遍比写完再改省时间。这五条是我每次做数据库实验都强制走完的检查项。表2数据库原理实验验收清单检查项验证方法合格标准GreatSQL服务自启动systemctl is-enabled greatsql输出enabledSELinux彻底关闭getenforce输出Disabled三张正式表数据完整SELECT COUNT(*) FROM 每张表行数与插入记录一致索引创建删除有痕迹SHOW INDEX FROM StudentsStudent_Dept存在Course_Cno被删除查询覆盖教材全部类别按WHERE/IN/BETWEEN/LIKE/DISTINCT逐类核对截图每类至少有一条查询和对应截图服务自启动这条最容易忽略很多同学装完当时能启动没配systemd enable重启虚拟机后数据库起不来实验三全在“连接不上数据库”里耗掉。所以验收时一定要检查systemctl is-enabled确保enabled状态。6.2 答辩准备三个高频追问和对应答法第一个追问“为什么关闭SELinux和防火墙”答法分两层SELinux是强制访问控制机制会限制mysqld进程的文件读写和网络通信权限而且策略配置复杂实验环境用不到关防火墙是为了保证3306端口监听不被默认策略拦截。第二个追问“为什么用二进制包而不用yum安装”答法落在观测性上yum装完二进制分散在系统目录里你只能看到“能用了”但看不到DBMS内部结构二进制包集中在独立目录bin、lib、share一目了然正好符合实验一“了解DBMS系统构架”的目标。第三个追问“SC表为什么用复合主键”答法回到业务语义一条选课记录由学号和课程号共同决定(Sno, Cno)组合唯一单独任何一列都不唯一复合主键表达的正是这个业务约束。这套实验流程完整走完之后我养成了一个习惯每次启动数据库服务一定先systemctl status和ps -ef双确认再开始写SQL。这个习惯救过我很多次因为很多所谓SQL问题根源其实是环境没起来导致的黑匣子。报告排版再好看查不出数据也只是空壳。希望帮到你。本文还有配套的精品资源点击获取