openGauss实验完全指南:从gsql连接、建表索引到事务死锁与JDBC入库
简介一份面向计算机科学与技术、软件工程专业学生的数据库实验报告书围绕《数据库系统原理》课程要求覆盖从认识DBMS到JDBC连接数据库的九个核心实验。内容包含实验目的、操作过程、截图结果与分析并针对openGauss环境下的数据库创建、SQL查询、视图、完整性控制、安全性设置、事务并发、备份恢复及编程连接等关键环节给出完整样例与讲解。资源为单个docx文档压缩包总大小约3.23MB排版清晰便于直接参考或改写提交。目前已有1520人学习适合正在完成数据库课程实验、期末报告或需要快速上手openGauss操作的高校学生使用。借助该报告书读者可系统掌握数据库基本操作与安全管理方法提升理论结合实践的能力。1. 一份能照着抄的openGauss实验报告书从gsql连库到JDBC入库的完整路径第一次做数据库实验的人最容易卡住的不是建表语句本身而是不知道在 openGauss 里连库之前还要先切换 omm 用户、启动服务、确认端口。这份 zzu 数据库实验报告书把这类容易忽略的步骤全部按实验顺序写了出来从认识 DBMS、创建数据库和表到视图、完整性、安全性、事务与并发、备份恢复最后落到 JDBC 连接数据库。它适合需要交数据库实验报告、或者想用 openGauss 完整跑一遍数据库课程设计流程的同学。相比于只给截图和结论的模板它的价值在于把每一条 gsql 命令、每一个约束写法都落在具体实验场景里照着敲就能复现报错也能从报告里的辨析部分找到原因。2. openGauss环境搭建与DBMS认知三种安装方式怎么选gsql连库参数逐项拆解这份报告书第一个实验就是“认识 DBMS 系统”很多人以为这一步只是开个虚拟机截两张图实际上安装方式和连接方式决定了后续八个实验能不能顺利进行。我在拆这份报告时最先看的就是它列出的三种安装模式因为选错方案后面全是连锁问题。2.1 三种安装模式怎么选虚拟机一键安装通常最省时间报告书明确写了 openGauss 有华为弹性云、虚拟机一键安装、先装 openEuler 再装 openGauss 三条路。三者的差异我整理成一张对比表安装方式适合场景时间成本主要坑点华为弹性云上安装需要远程访问、想在报告里展示云环境取决于网络和云主机配置安全组要放行 26000 端口否则本地连不上虚拟机一键安装本地复现实验交报告最快路径低虚拟网络模式别乱改改坏了 NAT 宿主机连不到库先装 openEuler 再装 openGauss想理解完整部署过程高依赖包、内核参数、字符集、用户组都可能出错华为弹性云适合需要把数据库放在云上的场景但安全组要放行数据库端口否则本地 gsql 连不上去排查起来比本地还麻烦。虚拟机一键安装是本地复现实验最快的方式镜像里数据库环境基本配好只需要启动虚拟机、切换 omm 用户、启动服务缺点是网络模式不要乱动。先装 openEuler 再装 openGauss 最接近生产环境的部署流程能让你在报告里多写几页安装步骤但任何一个环节出错安装日志看起来都像天书。我一般给的建议是目标只是交实验报告选第二种想在报告里展示完整部署过程的再考虑第三种。切换用户和启动服务的命令在实验报告里是必须出现的两行su - omm gs_om -t start逻辑说明omm 是 openGauss 安装时创建的数据库系统用户gs_om 是 openGauss 的集群运维工具。不切到 omm 用户直接执行 gs_om大概率会报权限错误。参数说明-t是 gs_om 的操作类型start代表启动集群su -里的短横线表示同时切换环境变量不是简单切用户。启动完成后建议顺手做一次健康检查gs_om -t status。这个命令输出集群状态显示 Normal 再往后走如果显示 Degraded多半是主备节点有问题先解决再连库。2.2 gsql连库参数拆解-d、-p、-r 分别控制什么连接默认数据库的命令报告书里的原样是gsql -d postgres -p 26000 -r参数说明-d指定要连接的数据库名postgres 是 openGauss 安装完成后默认生成的数据库第一次进去主要用于创建后续业务库-p指定端口号26000 是 openGauss 主节点默认端口部署时改过端口这里要跟着改-r是连接参数报告书里原样保留即可它不影响是否连得上真正容易写错的是前两个。连接成功后命令行提示符会变成postgres#。在这个提示符后面既可以输入标准 SQL也可以输入斜杠开头的元命令。第一次连库建议先执行select version();既能确认连上了也能给实验报告开头留一张环境验证截图。报告书在这里还特别解释了一个概念初始数据库只有安装时创建的管理员用户能访问其他用户要先用管理员建好账号才能连接。很多同学第一次用 postgres 用户没成功不是密码错而是用户不存在或没授权这个我放到第 5 章踩坑里细说。2.3 元命令速查查库、查表、查视图、查索引各用哪条gsql 里斜杠开头的命令叫元命令它们不打到数据库里只在客户端侧执行。报告书实验一列了一批我按使用频率整理成表命令作用常用场景\?查看帮助忘记命令时\l列出所有数据库等价语句select datname from pg_database;\c dbname切换数据库进入刚创建的库\dt列出当前 schema 下的表查看已建表\d列出表、视图、索引加表名查看属性查看表结构\d tablename查看表结构确认字段和约束\dn列出 schema检查模式建对没\di查看索引实验二截图用\db列出表空间等价语句select spcname from pg_tablespace;\h查看 SQL 命令帮助记不全语法时\q退出 gsql结束会话其中三条最容易在实验报告里用上。第一条是\l实验一要求截图数据库列表直接执行它就能看到 postgres 等库第二条是\d Teachers创建完表后查看属性报告要求截图下方有图编号和题注这张图就是表结构证据第三条是\di建完索引后截图能同时看到 DBMS 自动为主码建的索引和我们手动建的 Student_Dept 索引。报告书里还有一段“索引和目录”的辨析说索引是排序结构、加快记录定位目录是清单、展示结构。我补充一句两者最直观的差别是索引对查询性能有实际影响目录本身不参与查询路径。这个辨析写进报告分析部分时可以直接转化为自己的话。这一章还剩下一个问题schema 是什么。报告书的说法是schema 是数据库中的一个名字空间包含表、视图、存储过程等对象比如 book_eg 用户创建的所有对象合起来就是 book_eg 这个 schema。在实验二里创建模式后再建表表名要写成 schema 名.表名否则会落到默认的 public 里这个点下一章会用到。3. 建库建表建索引的实操细节表空间、Schema、约束与外键的落库顺序实验二的标题是“创建数据库、表和索引”。这一章的信息密度比实验一大得多因为它同时涉及对象创建顺序、约束写法、类型选择三个层面的知识。报告书的编排是“先给对象关系再给可执行 SQL”我按这个节奏拆开说。3.1 先建表空间还是先建数据库存储对象的依赖顺序在 openGauss 里数据最终落在表空间对应的物理目录上。报告书先创建表空间再创建数据库这个顺序就是依赖关系数据库要指定存储在哪个表空间里。两个命令连起来看create tablespace tpcds_local relative location tablespace/tablespace_1; create database db_sc with tablespace tpcds_local;逻辑说明第一条在数据目录下规划一块存储区域relative location是相对于数据目录的路径不是操作系统里随便一个目录第二条创建业务库 db_sc 时指定它使用刚才划分的 tpcds_local。参数说明表空间名和路径可以改但路径必须在数据库数据目录范围内tablespace 指定默认表空间不写就用数据库默认的 pg_default。创建完之后报告书演示了改名操作alter database db_sc rename to db_school;这个命令看起来简单实际执行时有个前提db_sc 上没有活动连接。如果有其他会话正连在这个库上alter database会一直等待像卡死了一样。实验报告里如果出现这种情况截图会被误以为命令不生效避免方法是先切到 postgres 库再执行改名或者把所有连接断开。数据库建好后用\c db_school切进去后续建表都在这一个库里完成。报告书里把这段归在“切换至数据库”小节很多同学漏了这一步结果表建到了 postgres 库最后截图里库名对不上。3.2 列级约束和表级约束表结构与外键的落库写法schema 可以理解为数据库里的一个命名空间。报告书里的演示是create schema book_eg; create table book_eg.Teachers(...); drop schema book_eg cascade;逻辑说明带 schema 前缀建表表明这张表的归属drop schema后面的 cascade 是关键它表示级联删除 schema 下的所有对象如果不带 cascade 而 schema 里已经有表会报错。实验报告里写级联删除的辨析比只贴命令更有分析成分。到这里真正要新建的表开始登场。报告书把建表顺序设计成 Teachers、Departments、Students、Courses、SC、Teaches。这个顺序不是随手写的Departments 的外键 Dheadno 引用 Teachers.TnoStudents 的外键 Dno 引用 Departments.Dno所以主表必须先存在。如果反着建报错信息会直接告诉你关系不存在。create table Teachers( Tno char(20) primary key, Tname char(20) not null, Sex char(20) check (Sex男 or Sex女), Birthday date, Title char(20), Dno char(20) );参数说明Tno 作为主键Tname 不允许为空Sex 用 CHECK 约束限定只能写男或女Birthday 用 date 类型存日期其他短文本字段用 char(20)。这里有一个值得写进报告的点char(20) 是定长字符不足 20 位也会补空格如果后续要和其他系统对接定长字段容易带出多余空格实际项目里更常用 varchar。但教材和实验环境里 char(20) 是标准答案按报告要求写就行。多列约束怎么放Departments 里有外键必须写在所有列定义之后create table Departments( Dno char(20) primary key, Dname char(20), Dheadno char(20), foreign key (Dheadno) references Teachers(Tno) );逻辑说明外键是典型的需要指定列名的约束所以写成表级约束放在字段定义后面用逗号分隔列级约束则紧跟列定义用空格分隔不需要写列名。报告书里专门辨析过列级约束可以覆盖单列场景表级约束适用于外键、联合主键这类跨列场景而且表级约束不支持 not null 和 default。这个辨析写进实验报告的分析部分非常合适。Students 表的外键指向 Departments.Dno写法与上面类似。Courses 表用了 smallintcreate table Courses( Cno char(20) primary key, Cname char(20) not null, Period smallint, Credit smallint );参数说明Period 和 Credit 分别存学时和学分取值范围小用 smallint 两个字节就够int 是四个字节。报告书里特意强调在满足取值范围的前提下优先用 smallint这句话放在报告里能体现你对类型长度的考虑。SC 表是选课关系表通常包含 Sno、Cno、Grade 三个字段Sno 和 Cno 联合作为主键还要分别对 Students 和 Courses 建立外键引用。联合主键必须用表级约束因为一个约束涉及两列。注意建表顺序按主表在前、从表在后反了会报 relation does not exist。3.3 索引不是建得越多越好主键索引与手动索引的分工索引在实验里的创建命令很短create index Student_Dept on Students(Dno);逻辑说明在 Students 表的 Dno 列上建立名为 Student_Dept 的索引目的是加速按院系查询。比如反复执行select * from Students where DnoD01有索引比全表扫描快这在数据量大的表上差别明显。数据量只有几百行的小表索引感觉不出来这就是很多人觉得索引是玄学的原因其实不是玄学是样本量太小。查看索引用\di输出里会同时出现两类一类是 DBMS 为主键自动创建的索引一类是我们手动创建的 Student_Dept。实验报告要求看的正是这个对比。删除索引drop index Student_Dept;逻辑说明删除后对 Dno 的查询回到全表扫描。实验报告如果要写有索引和没索引的区别可以用 explain 查看执行计划openGauss 里用explain select * from Students where DnoD01;能看到是否走索引扫描。这一步作为扩展内容放在报告末尾是加分项。4. 视图、完整性、安全性与并发控制四个实验对应四类数据保护机制实验四到实验七在报告目录里是四个独立章节但放在一起看更有价值视图管数据怎么查完整性管数据对不对安全性管谁能查事务并发管多人同时查怎么办。四个实验串起来就是数据库系统对数据的四类保护机制。4.1 视图查询抽象和最小权限的结合点视图在 openGauss 里可以理解成一个保存好的查询语句本身基本不占用额外物理空间每次查询时动态生成结果。实验四创建视图的常见写法是把多表连接封装起来create view v_student_dept as select Students.Sno, Students.Sname, Departments.Dname from Students join Departments on Students.Dno Departments.Dno;逻辑说明视图解决了两个问题。第一是查询抽象以后查学生所属院系直接select * from v_student_dept不需要每次重写 join第二是权限收窄只暴露姓名和院系不暴露生日等敏感字段。参数说明视图列名默认取 select 列表中列的名字也可以用create view v_student_dept(Sno, Sname, Dname) as ...的方式显式命名。删除视图是drop view v_student_dept;。实验报告里创建视图后要做两件事用 select 验证视图数据正确用\dv确认视图在列表里。如果 gsql 版本不支持\dv用select viewname from pg_views;也能查到。视图和基表的差别要写进分析视图不是物理存储的表不能对多表视图随意执行 insert、update、delete它对用户来说只读更常见。4.2 完整性控制让数据库拒绝脏数据完整性的三个层次是实体完整性、参照完整性、用户定义完整性。在已建好的表上验证约束是否生效的最直接办法是故意插入违反约束的数据并截图报错。比如主键重复insert into Students(Sno, Sname, Sex) values (2021001, 张三, 男); insert into Students(Sno, Sname, Sex) values (2021001, 李四, 男);逻辑说明第二条会报 duplicate key 错误说明主键约束拒绝了重复学号。把第二条的 Sno 改掉就能插入成功这是实体完整性的演示。外键验证insert into Students(Sno, Sname, Dno) values (2021002, 王五, D99);逻辑说明D99 在 Departments 里若不存在会触发外键 violates foreign key constraint 错误这是参照完整性的演示。CHECK 约束验证insert into Teachers(Tno, Tname, Sex) values (T001, 赵六, F);逻辑说明Sex 字段只接受中文男和女插入 F 会被拒绝这是用户定义完整性的演示。写实验报告时把错误截图和修改后的成功插入成对放比单独贴一条成功 SQL 更能说明你真的理解约束。实验五里还会遇到一类看起来像约束冲突的报错实际上是数据里带了全角空格这个放到下一章专门讲。4.3 安全性控制用户与角色分开管理实验六的安全性控制核心不是能不能连上数据库而是连上之后能对哪些对象做哪些操作。在 openGauss 里建用户、授权、收回权限的命令是这一组create user stu with password Stu123456; grant select on Students to stu; revoke select on Students from stu;参数说明create user的with password指定登录密码openGauss 对密码默认有复杂度要求太短或太简单会被拒绝grant select on Students to stu的含义是允许 stu 用户查询 Students 表revoke是反向操作回收权限。报告书里有一段很实用的辨析用户是具体账户角色是账户集合。部门来了新员工分配一个角色就拿到一组权限员工调岗换个角色即可。这个思路对应到数据库上就是先建角色、再授权限、最后把角色授予用户create role read_only; grant select on all tables in schema public to read_only; grant read_only to stu;逻辑说明read_only 角色被赋予 public schema 下所有表的查询权限再把角色授予 stu 用户stu 就拥有了这个角色对应的权限。注意角色授权后要重新连接数据库才会生效。安全性实验的验证方法是用 stu 用户重新连接查询 Students 能成功尝试 update 或 drop 会报权限不足。实验报告里保留有权限查询成功和无权限操作被拒两张截图分析部分写最小必要权限原则这一章就完整了。4.4 事务与并发锁等待和死锁的经典复现实验七的事务部分最基础的演示是手动控制提交与回滚begin; update Courses set Credit 4 where Cno C001; rollback;逻辑说明begin 开启事务update 修改数据rollback 回滚后这条 update 如同没发生过。把 rollback 换成 commit变更才会永久生效。这个操作直观展示了事务的原子性。并发部分通常用两个 gsql 会话演示。一个会话更新某一行但不提交另一个会话试图更新同一行此时第二个会话会进入锁等待直到第一个会话提交或回滚。这个场景截图非常直观也适合作为数据库并发锁的实证材料。死锁的复现要两个事务交叉申请资源-- 会话1 begin; update Courses set Credit 5 where Cno C001; -- 会话2 begin; update Courses set Credit 5 where Cno C002; -- 会话1继续 update Courses set Credit 5 where Cno C002; -- 会话2继续 update Courses set Credit 5 where Cno C001;逻辑说明会话1持有 C001 行锁并请求 C002会话2持有 C002 行锁并请求 C001形成循环等待。数据库检测到死锁后会回滚其中一个事务释放锁让另一个完成。这个场景要写进报告核心。处理数据库锁问题时pg_stat_activity 是最常用的排查视图select pid, state, wait_event_type, query from pg_stat_activity where state active;参数说明pid 是会话进程号query 是正在执行的语句wait_event_type 显示等待类型。锁等待和死锁都从这个视图找源头再用pg_terminate_backend(pid);结束阻塞会话。注意生产环境不要随手杀会话先确认它不是业务核心事务。5. 九个实验的避坑指南从安装失败到死锁的五条踩坑记录这一章把我在拆这份报告时总结出的五个高频问题逐一列出来。每条踩坑记录都是现象、原因、解决的结构实验报告书里要求写的“遇到的问题如何更正”在这里有现成素材。5.1 连接不上数据库服务没启动或用户没切对现象执行gsql -d postgres -p 26000 -r后卡住不动或直接报 could not connect to server在 openGauss 上更常见的是 permission denied。原因连不上有两种典型原因。第一种是gs_om -t start没有执行或执行失败数据库服务根本没起来端口 26000 上没有进程监听。第二种是当前系统用户不是 ommopenGauss 出于安全设计只允许安装用户操作数据库集群普通用户即使敲同样的命令也会被拒绝。还有一部分是端口或网络问题在虚拟机上尤其常见。解决按顺序执行两条命令再确认端口su - omm gs_om -t start ss -lntp | grep 26000参数说明grep 26000 是为了确认端口在监听如果这一行没有输出说明服务没起来继续看 gs_om 的报错日志如果输出里有监听再执行 gsql 连接。云主机则要检查安全规则是否放行 26000。我把这条放在第一位因为后面所有实验都依赖它能连通。5.2 创建表空间报错relative location 路径不一定自动存在现象执行create tablespace tpcds_local relative location tablespace/tablespace_1;时报错提示目录或权限错误。原因relative location是相对路径相对于数据库的数据目录但 tablespace/tablespace_1 这个层级在数据目录下不一定存在。不同版本对目录不存在的处理方式有差异有些版本不会自动创建导致建表空间失败。解决先确认数据目录再手动补目录mkdir -p $(gs_initdb --showdatadir)/tablespace/tablespace_1逻辑说明gs_initdb --showdatadir输出数据目录位置mkdir -p确保目标层级存在。如果不想动目录也可以把relative location改成数据目录下已存在的路径。这个坑的特点是报错信息不直观容易被误读成权限问题实际上是路径问题。实验报告的“问题更正”部分写这个比写重启解决可信得多。5.3 建表顺序反了外键引用的表还不存在现象执行create table Students时报错 relation departments does not exist。原因Students 表的 Dno 外键引用了 Departments.Dno而 Departments 还没创建。外键约束定义时被引用表必须已经存在数据库不会因为你后面会建就允许你先建从表。解决按 Teachers、Departments、Students、Courses、SC、Teaches 的顺序建。如果表已经建了一半不用删除重建用 alter table 补外键alter table Students add constraint fk_students_dno foreign key (Dno) references Departments(Dno);参数说明约束名 fk_students_dno 可以自己定义方便以后用alter table ... drop constraint fk_students_dno;删除。这个方案也适合报告书里已有的表需要追加约束的场景。记住了这条建六张表的实验基本一次过。5.4 INSERT被CHECK约束拒绝不一定是约束写错先查数据现象Sex 列明明写的男插入却报 check 约束错误看不出原因。原因多半是数据里带了不可见字符比如从 Excel 或 Word 复制过来引号、全角空格、换行符都可能在字段值里。约束只认字符本身男和男加全角空格是不同的值。另一种常见情况是应用传了 M/F而约束只认中文。解决先查字段长度确认是否有隐藏字符select Tno, length(Sex), Sex from Teachers;逻辑说明length 返回字符数如果看到长度和显示内容不一致清理数据后重试。去掉不可见字符可以用replace(Sex, , )注意这里的空格要替换成实际的全角字符。这个坑在实验五特别常见因为 CHECK 约束是这一章的主角报错信息又常常被误解为约束冲突其实是数据质量问题。截一条隐藏字符导致的报错和清理后的成功插入问题分析能写得很有现场感。5.5 锁等待和死锁两个会话卡住不动时先查 pg_stat_activity现象两个 gsql 窗口各自执行 update 后同时卡住几秒或几十秒后其中一个窗口报 deadlock detected 并回滚。原因卡住的原因是第一个事务 update 后没有提交行锁一直持有第二个事务更新同一行时只能等待。死锁则是因为两个事务按相反顺序更新两张不同的表或两行不同的数据形成循环等待。数据库死锁检测机制检测到循环后会选择回滚代价较小的一方来打破等待。解决先查阻塞源select pid, state, wait_event_type, query from pg_stat_activity where state active;参数说明wait_event_type 如果显示 LWLock 或 Lock说明在等锁。找到阻塞会话后用pg_terminate_backend(pid);结束它事务回滚锁自然释放。更根本的解决方法是让所有事务按同一顺序访问资源比如先更新 C001 再更新 C002不交叉申请。实验报告里写数据库检测到死锁后自动回滚事务这一句配合报错截图比单纯贴两条 update 有分析深度。6. 交报告前的最后验证用一组SQL确认九组实验都真的跑通了在交实验报告之前我会把九组实验的成果用一小段验证流程重新过一遍避免截图里数据和实际环境对不上。第一轮核对对象是否建齐\l \dt \di \dv \db逻辑说明这五行分别罗列数据库、表、索引、视图、表空间清单。如果实验二到实验四的对象都建了这五个命令的输出就是最好的证据。需要补充一点\dv在部分 gsql 版本里不可用用select viewname from pg_views;替代。第二轮核对数据是否有效select count(*) from Students; select count(*) from SC;逻辑说明行数和你插入的数据量一致说明建表、插数、事务提交都成功了。如果事务演示中用 rollback 回滚过那部分数据不应该出现在这里这个细节能证明事务实验真做了。第三轮核对权限和完整性是否生效select * from pg_indexes where tablename students; select * from pg_constraint where conrelid teachers::regclass;逻辑说明第一句看 Students 表上的索引第二句看 Teachers 表上的约束主键、CHECK、外键都在 pg_constraint 里查出来比截图更完整。完整性实验可以故意再插一条脏数据让报错然后回滚或删除确保最后库里没有脏数据。到这里报告里要求的截图就都有了连库成功、建表、插入数据、报错、权限拒绝、锁等待每一类实验都有一张能对上号的图。排版上再按报告要求把图编上号、表格带标题、段首空两格基本不会被打回重写。说句实在话我刚开始做这类实验时最烦的就是截图和命令对不上后来养成了一个习惯每完成一个实验立刻把\l、\dt、\di的输出存到一个文本文件里最后交作业前对照清单过一遍发现少了哪张表马上能定位。从那以后我每次补数据库实验记录都强制走一遍这个流程截图不再临时抓交报告也不会心虚。希望帮到你。本文还有配套的精品资源点击获取