☰
南华大学数据库原理实验报告:SQL Server建库到SELECT查询完整实战
2026/10/2 21:40:42 网站建设 项目流程

简介:这份南华大学《数据库原理》实验报告面向大数据技术等专业学生,用于课程实验的参考与复盘,帮助读者系统掌握数据库管理系统认识、SQL语言应用与数据库设计基础。报告围绕SQL Server Management Studio展开,涵盖数据库与数据表的创建、主码外码与默认值约束、表间一对多与多对多关系,以及单表查询、多表连接查询、数据更新等实验内容,并附有实验总结。资源包共1个doc文件,约5.38MB,内容为完整实验报告文档,包含实验题目、实验要求、实验代码与结果记录,便于对照学习。目前已有374人学习下载,适合需要完成数据库原理实验、巩固SQL查询与建库建表操作的学习者参考。

1. 南华大学数据库原理实验报告:从建库到查询,一套能跑通的完整路径

如果你正在搜「南华大学数据库原理实验报告」,大概率是两种情况:要么实验课刚布置下来,对着 SQL Server 的安装界面发懵;要么报告写到一半,SELECT 查不出想要的结果,GROUP BY 一加就报错。这篇不讲课程大纲,只讲怎么把这份实验从零跑通——建库、建表、插数据、写查询、调错、截图交报告,每一步都有可复现的命令和参数说明。

数据库原理这门课的实验,核心不是让你背范式定义,而是让你亲手感受 DBMS 到底怎么管数据。SQL Server 是多数高校的默认环境,SSMS 是主要操作界面,SELECT 是贯穿始终的主角。下面按真实做实验的顺序展开,新手能跟着敲,熟手可以跳到避坑那章看参数边界。

2. 实验环境搭建:SQL Server 与 SSMS 的安装配置

2.1 版本选择与安装前的三个检查点

SQL Server 版本很多,实验课通常指定 2016、2019 或 2022。如果老师没指定,我一般选 SQL Server 2019 Developer 版——功能完整、对教学场景免费、和 SSMS 18.x 以上兼容性好。下载渠道走微软官方,不要用来路不明的整合包,否则后面连不上实例时你分不清是配置问题还是安装包被改过。

安装前先确认三件事。第一,系统盘至少留 6GB 空间,SQL Server 的共享功能目录很占地方。第二,关掉 360 或火绒的实时防护,它们会拦截 SQL Server 的端口监听,导致装完服务起不来。第三,记下你设置的实例名,默认实例就是机器名,命名实例形如机器名\SQLEXPRESS,后面连接字符串全靠它。

安装类型选「基本」还是「自定义」?实验课建议选自定义,因为要勾选「数据库引擎服务」和「客户端工具连接」。功能选择页里,数据库引擎服务是必须的,SQL Server 复制和机器学习服务可以取消,省空间也省安装时间。实例配置选默认实例,排序规则保持默认的Chinese_PRC_CI_AS,这个排序规则对中文实验数据友好,不会出现乱码比较。

服务器配置页,SQL Server 数据库引擎的启动类型设为自动,账户用 NT AUTHORITY\SYSTEM 即可。数据库引擎配置页,身份验证模式选「混合模式」,设置 sa 密码。这里有个血泪经验:密码要满足复杂度(大小写+数字+符号),否则下一步过不去,很多人卡在这里反复重装。

装完后打开 SSMS,连接界面服务器类型选「数据库引擎」,服务器名称填localhost或.\SQLEXPRESS(看你装的实例),身份验证先用 Windows 身份验证进去。进去后右键服务器属性,确认版本号和排序规则,截图放进报告的环境说明部分。

2.2 用 SSMS 连接并验证实例可用

连接成功后,在对象资源管理器里展开「数据库」,如果能看到 master、model、msdb、tempdb 四个系统数据库,说明引擎正常。接着新建一个查询窗口,敲下面这行验证:

-- 查看当前实例版本与默认排序规则 SELECT @@VERSION AS 版本信息, SERVERPROPERTY('Collation') AS 排序规则;

@@VERSION返回完整版本字符串,SERVERPROPERTY('Collation')返回实例级排序规则。如果排序规则不是 Chinese_PRC_CI_AS,后面建表时中文字段比较可能出问题,可以在建库时单独指定。

再验证 sa 账户能不能用。断开当前连接,重新连接时身份验证选「SQL Server 身份验证」,登录名 sa,密码是你设的那个。能进去说明混合模式生效。进不去就回服务器属性→安全性,确认「SQL Server 和 Windows 身份验证模式」被选中,然后重启 SQL Server 服务。

提示:如果 SSMS 报「无法连接到服务器」,先看 SQL Server 服务是否在运行(services.msc 里找 SQL Server (MSSQLSERVER)),再看 TCP/IP 协议是否启用(SQL Server 配置管理器→网络配置→协议)。

3. 建库建表与数据填充:把实验数据落进磁盘

3.1 创建实验数据库与文件组参数

实验报告一般要求建一个学生选课库或图书管理库。我以学生选课为例,库名StudentCourseDB。建库语句要显式指定数据文件和日志文件的路径、初始大小和增长方式,这些参数在报告里要写清楚,老师看的就是你懂不懂物理存储。

-- 创建学生选课数据库,显式指定物理文件参数 CREATE DATABASE StudentCourseDB ON PRIMARY ( NAME = 'StudentCourseDB_Data', FILENAME = 'D:\SQLData\StudentCourseDB_Data.mdf', SIZE = 20MB, MAXSIZE = 200MB, FILEGROWTH = 10MB ) LOG ON ( NAME = 'StudentCourseDB_Log', FILENAME = 'D:\SQLData\StudentCourseDB_Log.ldf', SIZE = 10MB, MAXSIZE = 100MB, FILEGROWTH = 5MB );

SIZE是初始大小,FILEGROWTH是每次自动增长量。为什么不设百分比增长?因为百分比在大库上会一次增长几个 GB,拖慢写入。固定 10MB 增长在教学库里够用,生产库一般按 64MB 或 256MB 起步。MAXSIZE设上限是防止日志文件失控撑爆磁盘,实验环境设 100MB 足够。

建完库用USE StudentCourseDB;切换上下文,再确认文件路径:

-- 查看数据库文件的实际落盘位置与当前大小 SELECT name AS 逻辑名, physical_name AS 物理路径, size * 8 / 1024 AS 大小MB FROM sys.database_files;

sys.database_files是系统视图,size字段单位是页(8KB),乘 8 除 1024 换算成 MB。这个查询在报告里可以作为「数据库物理结构验证」的截图。

3.2 三张核心表的结构设计与约束

学生选课库最少三张表:学生表 Student、课程表 Course、选课表 SC。建表时主键、外键、非空、默认值、CHECK 约束都要体现,这是数据库原理实验的评分点。

-- 学生表:学号主键,姓名非空,性别限定取值,年龄有范围约束 CREATE TABLE Student ( Sno CHAR(10) PRIMARY KEY, Sname NVARCHAR(20) NOT NULL, Ssex NCHAR(2) CHECK (Ssex IN (N'男', N'女')), Sage INT CHECK (Sage BETWEEN 15 AND 60), Sdept NVARCHAR(30) DEFAULT N'计算机学院' ); -- 课程表:课程号主键,学分有范围约束 CREATE TABLE Course ( Cno CHAR(6) PRIMARY KEY, Cname NVARCHAR(40) NOT NULL, Ccredit DECIMAL(3,1) CHECK (Ccredit > 0 AND Ccredit <= 10) ); -- 选课表:联合主键,外键关联学生和课程,成绩允许为空 CREATE TABLE SC ( Sno CHAR(10) NOT NULL, Cno CHAR(6) NOT NULL, Grade DECIMAL(5,1) CHECK (Grade BETWEEN 0 AND 100), PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno), FOREIGN KEY (Cno) REFERENCES Course(Cno) );

CHAR(10)和NVARCHAR(20)的区别要讲清楚:学号定长用 CHAR,姓名变长且含中文用 NVARCHAR。NCHAR(2)存一个汉字刚好,因为 N 前缀表示 Unicode。CHECK 约束在插入非法数据时会直接拒绝,比应用层校验更可靠。

SC 表用(Sno, Cno)联合主键,天然保证一个学生同一门课只能选一次。两个外键分别指向 Student 和 Course,删除学生时如果有选课记录,默认会阻止删除,这就是参照完整性。

3.3 插入实验数据与批量填充技巧

逐条 INSERT 太慢,实验数据一般十几到几十条,用多行 VALUES 一次插入。

-- 批量插入学生数据 INSERT INTO Student (Sno, Sname, Ssex, Sage, Sdept) VALUES ('2023001', N'张三', N'男', 20, N'计算机学院'), ('2023002', N'李四', N'女', 19, N'计算机学院'), ('2023003', N'王五', N'男', 21, N'软件学院'), ('2023004', N'赵六', N'女', 20, N'软件学院'); -- 批量插入课程数据 INSERT INTO Course (Cno, Cname, Ccredit) VALUES ('C001', N'数据库原理', 4.0), ('C002', N'操作系统', 3.5), ('C003', N'计算机网络', 3.0); -- 插入选课与成绩 INSERT INTO SC (Sno, Cno, Grade) VALUES ('2023001', 'C001', 88.5), ('2023001', 'C002', 76.0), ('2023002', 'C001', 92.0), ('2023003', 'C003', 85.5), ('2023004', 'C001', NULL);

注意最后一条 Grade 为 NULL,这是故意留的——后面做 NULL 值查询和聚合函数排除 NULL 的实验要用。插入完用SELECT * FROM Student;验证,如果中文显示成问号,说明列用了 VARCHAR 而不是 NVARCHAR,或者插入时漏了 N 前缀。

注意:如果插入报「违反 CHECK 约束」,检查 Ssex 是否写了 N'男',Grade 是否在 0-100 之间。报「违反 PRIMARY KEY 约束」说明主键重复,报「违反 FOREIGN KEY 约束」说明引用了不存在的学号或课程号。

4. SELECT 查询实验:从单表到多表连接的递进

4.1 单表查询与 WHERE 条件的边界

单表查询是 SELECT 的基本功。实验报告通常要求覆盖:条件查询、范围查询、模糊查询、空值查询、排序、去重。

-- 查询计算机学院年龄大于等于20的学生,按年龄降序 SELECT Sno, Sname, Sage FROM Student WHERE Sdept = N'计算机学院' AND Sage >= 20 ORDER BY Sage DESC; -- 查询姓张的学生(模糊查询) SELECT Sno, Sname FROM Student WHERE Sname LIKE N'张%'; -- 查询成绩为空的学生选课记录(空值不能用 = NULL) SELECT Sno, Cno FROM SC WHERE Grade IS NULL; -- 查询所有被选过的课程号(去重) SELECT DISTINCT Cno FROM SC;

LIKE N'张%'里的%匹配任意长度字符,_匹配单个字符。空值判断必须用IS NULL,写= NULL永远返回空结果集,这是新手最常见的翻车点。DISTINCT作用于整行,如果 SELECT 多列,去重的是列的组合。

排序时DESC降序、ASC升序(默认)。如果排序列有 NULL,SQL Server 把 NULL 当最小值,升序时排最前。想控制 NULL 位置可以用ORDER BY CASE WHEN Grade IS NULL THEN 1 ELSE 0 END, Grade。

4.2 聚合函数与 GROUP BY 的分组逻辑

聚合查询是实验报告的重头戏,也是报错最集中的地方。

-- 统计每门课程的选课人数和平均分 SELECT Cno, COUNT(*) AS 选课人数, AVG(Grade) AS 平均分, MAX(Grade) AS 最高分, MIN(Grade) AS 最低分 FROM SC GROUP BY Cno; -- 只统计有成绩的记录,排除NULL SELECT Cno, AVG(Grade) AS 有效平均分 FROM SC WHERE Grade IS NOT NULL GROUP BY Cno HAVING AVG(Grade) >= 80;

COUNT(*)统计行数包含 NULL,COUNT(Grade)不包含 NULL。AVG(Grade)自动忽略 NULL,所以如果某门课只有一条 NULL 成绩,AVG 返回 NULL 而不是 0。WHERE在分组前过滤行,HAVING在分组后过滤组,顺序不能颠倒。

SELECT 列表里非聚合列必须出现在 GROUP BY 里,否则报「列在选择列表中无效,因为该列未包含在聚合函数或 GROUP BY 子句中」。这是 SQL Server 的硬性规则,不是玄学。

4.3 多表连接查询与连接方式选择

三张表关联查询是实验的最终目标。

-- 内连接:查询每个学生的选课和成绩,含课程名 SELECT s.Sno, s.Sname, c.Cname, sc.Grade FROM Student s INNER JOIN SC sc ON s.Sno = sc.Sno INNER JOIN Course c ON sc.Cno = c.Cno ORDER BY s.Sno, c.Cno; -- 左外连接:查所有学生,没选课的也显示出来 SELECT s.Sno, s.Sname, sc.Cno, sc.Grade FROM Student s LEFT JOIN SC sc ON s.Sno = sc.Sno; -- 查询没选任何课的学生 SELECT s.Sno, s.Sname FROM Student s LEFT JOIN SC sc ON s.Sno = sc.Sno WHERE sc.Sno IS NULL;

INNER JOIN 只返回两表都匹配的行,LEFT JOIN 保留左表全部行、右表无匹配填 NULL。查「没选课的学生」用 LEFT JOIN + IS NULL 是标准套路,比 NOT IN 更安全,因为 NOT IN 遇到子查询里有 NULL 会返回空结果集。

连接条件写在 ON 后面,过滤条件写在 WHERE 后面。左外连接时如果把右表过滤条件写在 WHERE 里,会退化成内连接,这是很多人踩过的坑。

5. 实验报告避坑与常见报错排查

5.1 连接失败与身份验证报错

现象:SSMS 连接报「无法连接到 localhost」,错误号 18456 或 4060。原因:18456 是登录失败,通常是 sa 密码错或混合模式没启用;4060 是实例名写错或服务没启动。解决:services.msc 确认 SQL Server 服务运行中;SQL Server 配置管理器确认 TCP/IP 已启用并重启服务;服务器属性→安全性确认混合模式;sa 账户在「登录名」里确认未被禁用。

5.2 中文乱码与排序规则冲突

现象:插入的中文显示成??或查询比较时匹配不到。原因:列定义用了 VARCHAR 而非 NVARCHAR,或插入字符串漏了 N 前缀。解决:建表时中文字段一律 NVARCHAR/NCHAR;插入时字符串前加 N,如N'张三';已建的表用ALTER TABLE ... ALTER COLUMN改类型,但已有数据可能丢失,实验阶段建议删表重建。

5.3 GROUP BY 报「列无效」

现象:SELECT Sname, AVG(Grade) FROM SC GROUP BY Cno报列 Sname 无效。原因:Sname 不在 GROUP BY 里也不是聚合函数,SQL Server 不知道取哪一行的值。解决:把 Sname 加进 GROUP BY,或者用聚合函数包起来如MAX(Sname)。如果确实想按学生分组,GROUP BY 应该写 Sno 而不是 Cno。

5.4 外键约束导致插入或删除失败

现象:插入 SC 记录报「与外键约束冲突」,或删除 Student 记录报「REFERENCE 约束冲突」。原因:插入的 Sno/Cno 在父表不存在,或删除的父表行还有子表引用。解决:先插父表再插子表;删除时先删子表记录再删父表,或者建外键时加ON DELETE CASCADE(实验报告里要说明级联删除的语义)。

5.5 数据库文件路径不存在导致建库失败

现象:CREATE DATABASE 报「无法创建文件,因为路径不存在」。原因:FILENAME 里写的D:\SQLData\目录没提前建。解决:先在文件资源管理器建好目录,或者改用默认路径(不写 FILENAME,让 SQL Server 放到默认 data 目录)。实验报告里建议显式指定路径并截图目录结构,体现对物理存储的理解。

6. 把实验报告写出工程味:查询优化与执行计划初探

实验报告如果只贴 SQL 和截图,拿不到高分。加一节执行计划分析,立刻拉开差距。SSMS 里选中查询按 Ctrl+M(或点「包括实际执行计划」),再执行,结果页会多一个「执行计划」标签。

看三个东西:表扫描 vs 索引查找、预估行数 vs 实际行数、最耗时的算子。如果 SC 表数据量小,优化器可能直接全表扫描,这是正常的。但你可以手动加索引看变化:

-- 在SC表的Cno列建非聚集索引 CREATE NONCLUSTERED INDEX IX_SC_Cno ON SC(Cno); -- 再次执行按课程号分组的查询,对比执行计划 SELECT Cno, COUNT(*) AS 人数, AVG(Grade) AS 平均分 FROM SC GROUP BY Cno;

建索引后再看执行计划,原本的「聚集索引扫描」可能变成「索引查找 + 键查找」,逻辑读次数下降。在报告里放两张执行计划截图对比,说明索引对分组查询的加速作用,这比单纯写「索引能加快查询」有说服力得多。

再进一步,用 SET STATISTICS IO 看逻辑读:

SET STATISTICS IO ON; SELECT * FROM SC WHERE Cno = 'C001'; SET STATISTICS IO OFF;

消息页会输出「表 'SC'。扫描计数 1,逻辑读取 X 次」。建索引前后对比这个数字,逻辑读下降就是优化生效的直接证据。这个技巧我在实际项目里也常用,实验阶段养成习惯,工作后排查慢 SQL 会顺手很多。

最后一个习惯:每写完一段实验 SQL,先SELECT TOP 5 *看看数据长什么样,再写复杂查询。我见过太多人直接写五表连接,结果查出来空集,回头逐表排查花半小时。先看数据、再写逻辑、最后加约束,这个顺序能省下大量返工时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询