简介:这是一份基于数据库的图书管理系统实训报告PDF,面向学习数据库原理与系统开发的在校学生及初学者,可用于参考实训报告结构、理解从需求分析到系统实现的全过程。报告从课题简介、实训目的与意义出发,依次涵盖需求分析、E-R概念模型设计、关系模式逻辑设计、详细建表及前端界面实现,并附有SQL Server建库建表代码和VB界面设计思路,能帮助读者快速把握数据库应用开发的完整脉络。包内包含单个PDF文件,压缩包约385KB,内容精炼。目前已有89人学习下载,适合需要完成类似实训作业或复习数据库设计方法的人群。通过这份报告,读者可直观看到学生表、图书表、管理员表的关系模式,了解图书查询、借阅、归还及身份权限划分的实现方式,对巩固SQL语句和数据库设计能力有实际参考价值。
1. 数据库图书管理系统实训报告:一份能直接抄作业的完整开发流水线
这份《数据库图书管理系统实训报告》不是那种只有目录和空话的应付文档,它把一套基于 SQL Server 2010 + VB.NET 的图书管理系统从需求分析、E-R 图、关系模式,一路写到了建库脚本和 WinForms 界面代码。换句话说,它是一份“理论先立住、动手能复现”的完整实训档案,适合正在做数据库课程设计、或者想快速搭一个图书管理 Demo 的从业者。你不需要去翻十几篇博客拼凑流程,这份报告把数据库设计和增删改查的核心闭环都摊开在了纸面上。我拆完这份材料之后的感觉是:它比市面上很多“只贴代码不给思路”的资源要扎实得多,但里面的连接字符串、表结构和登录逻辑也确实有需要动手改的地方。下面我按实际复现的顺序,把这份资源从头到尾走一遍。
2. 数据模型先行:从 E-R 图到五张关系表的映射逻辑
2.1 实体与关系:先看清这份报告的数据建模思路
这份实训报告在概念模型设计阶段给的是经典 E-R 图,涉及四个实体和两个联系:
- 学生(学号,姓名,性别,班级,联系电话)
- 图书(书号,书名,作者,定价,数量,分类号,出版社名称)
- 管理员(编号,密码,姓名,联系电话)
- 借阅联系:学生与图书之间是多对多(m:n),借阅关系上附带借阅时间和借阅量
- 管理联系:管理员与图书之间也是多对多(m:n),附带管理日期和备注
从 E-R 图向关系模型转换时,报告给出的处理方式是:把多对多联系拆成独立的“借阅”表和“管理”表,主键分别取两个外键的组合。这个转换思路和教材里的标准做法一致——多对多关系不能直接合并进实体表,必须拆中间表。拆完之后五张表的结构如下:
| 表名 | 字段 | 主键 |
|---|---|---|
| student | 学号、姓名、性别、班级、联系电话 | 学号 |
| books | 书号、书名、作者、定价、数量、分类号、出版社 | 书号 |
| administrator | 编号、密码、姓名、联系电话 | 编号 |
| borrow | 学号、书号、借阅时间、借阅量 | 学号 + 书号(联合主键) |
| management | 编号、书号、管理日期、备注 | 编号 + 书号(联合主键) |
我一般会在这一步额外做一件事:检查外键约束。报告里没有写 FOREIGN KEY,但在实际建库时,borrow 表的学号和书号、management 表的编号和书号,都应该加上外键引用,否则会出现“借阅记录关联了不存在的学生”这类脏数据。这个后面会单独说。
2.2 逻辑模型设计:字段类型和规范化的取舍
报告里所有字段统一用 varchar(200),部分用 varchar(100) 或 varchar(400)。这是实训项目的典型做法——为了省事,全部用变长字符串。好处是从前端取值拼接 SQL 时不用考虑类型转换,坏处是排序和范围查询的效率会打折扣,而且“借阅量”这种数值字段用 varchar 存,后续做统计函数(SUM、AVG)时还得 CAST。
关于规范化,报告里的关系模式基本满足 3NF:每个非主属性都直接依赖主键,没有传递依赖。出版社名称直接存在 books 表里算是一个冗余点,严格来说应该拆一张出版社表,但实训规模下这么做可以接受。我会保持原样,不额外拆表——因为你加表就意味着前端代码和 DataGridView 绑定逻辑全要改,实训报告的价值在于闭环跑通,不在于理论上的极致规整。
逻辑模型设计还有个容易被忽略的点:视图设计。报告内容里提到了视图设计但没有给出具体视图代码。若你自己复现时想加上,一个实用的视图是“借阅明细”,把 borrow、student、books 三张表 JOIN 起来,这样前台查询时一条 SELECT 就能拿全信息,不用每次 JOIN 写三遍。
3. 建库脚本实操:把 books_management 数据库完整跑起来
3.1 数据库与五张表的创建脚本
报告第 5.1 节给了完整的建库建表代码,我先按原样整理一遍,再补上实际跑通需要的修正:
create database books_management on ( name = 'books_management', filename = 'D:\books_management.mdf', size = 10, maxsize = 10, filegrowth = 10 ) log on ( name = 'books_management_log', filename = 'D:\books_management_log.ldf', size = 10, maxsize = 10, filegrowth = 10 ) go create table student ( 学号 varchar(200) primary key, 姓名 varchar(200) not null, 性别 varchar(100) not null default '男', 班级 varchar(200) not null, 联系电话 varchar(400) not null ) create table books ( 书号 varchar(200) primary key, 书名 varchar(200) not null, 作者 varchar(200) not null, 定价 varchar(200) not null, 数量 varchar(200) not null, 分类号 varchar(200) not null, 出版社 varchar(200) not null ) create table administrator ( 编号 varchar(200) primary key, 密码 varchar(200) not null, 姓名 varchar(100) not null, 联系电话 varchar(400) not null ) create table borrow ( 学号 varchar(200) not null, 书号 varchar(200) not null, 借阅时间 varchar(100) not null, 借阅量 varchar(400) not null, primary key(学号, 书号) ) create table management ( 编号 varchar(200) not null, 书号 varchar(200) not null, 管理日期 varchar(100) not null, 备注 varchar(400) not null, primary key(编号, 书号) )逻辑说明:整体分两步,先建库再建表。建库时设置了主数据文件(.mdf)和日志文件(.ldf)的初始大小均为 10MB、最大 10MB,filegrowth 设为 10MB。注意这里的 maxsize=10 意味着数据库文件不会自动增长超过 10MB,实训数据量小够用,但如果你要插入几千条测试数据,建议把 maxsize 改成 -1(不限制)或者调大,否则会报“文件已满”错误。建表部分五张表全部显式指定主键:student、books、administrator 用单一主键,borrow 和 management 用联合主键。
3.2 抄这份脚本前必须改的三个点
原报告的建库脚本里 filename 路径写的是“图书管理数据库\books_management.mdf”,这是一个不完整的 Windows 路径。我一开始按原样执行直接报错,因为 SQL Server 要求绝对路径。改成D:\books_management.mdf就正常了。另外,create database语句末尾原报告有Go,这是 SQL Server Management Studio(SSMS)的批处理分隔符,在 SSMS 里执行没问题,但如果你用 sqlcmd 或在 C# 代码里执行整段脚本,Go需要删掉或替换成分号。
第三个要改的地方是 student 表。原报告后面登录代码里查的是“学号和密码”,但建表语句里 student 表压根没有密码字段。如果照抄,学生登录功能必然是失败的——执行select * from student where 学号='...' and 密码='...'会直接报“列名无效”。我自己复现时加了一列:密码 varchar(200) not null default '123456',默认密码设为 123456。管理员登录不受影响,因为 administrator 表本身有密码字段。
为验证建库成功,可以在 SSMS 里执行:
select name from sys.databases where name = 'books_management' go use books_management go select * from sys.tables返回结果中应该包含 student、books、administrator、borrow、management 五张表。注意中文字段名在 SQL Server 中是允许的,但这依赖数据库的排序规则。如果建库时不指定 collation,默认排序规则通常支持中文,但建议在建库语句里显式加上collate Chinese_PRC_CI_AS,避免在部分英文版 SQL Server 实例上出现中文乱码。
4. 前台界面代码拆解:VB.NET 登录、查询和增删改查怎么联动
4.1 入口窗体:角色分流的设计逻辑
前端部分,报告用 VB.NET(Visual Basic .NET)在 Visual Studio 2010 里建了多个 WinForms 窗体。系统入口 Form1 上有两个按钮:“学生”和“管理员”。代码逻辑很简单:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' 窗体加载时无需额外初始化,保持空白即可 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Form2.Show() ' 学生登录窗体 End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Form3.Show() ' 管理员登录窗体 End Sub End Class参数与逻辑说明:两个按钮事件分别 Show 出 Form2(学生登录)和 Form3(管理员登录),Form1 本身不隐藏。这里有个细节值得注意——用Form2.Show()而不是Form2.ShowDialog(),意味着用户可以同时打开多个窗口。实训演示时问题不大,但严格做法是用 ShowDialog 或先 Me.Hide() 再 Show,否则反复点按钮会叠出多个登录框。
4.2 登录验证:数据库连接字符串是这套系统的命门
Form2 是学生登录窗体。它的核心是checkLoginName()子过程,连接字符串和查询逻辑都写在这里:
Sub checkLoginName() Dim strcon As String = "data source=XP23;initial catalog=books_management;user id=XP23\Administrator;pwd=;integrated security=true;" Dim con As SqlConnection = New SqlConnection(strcon) con.Open() Dim sql As String = "select * from [student] where 学号='" & TextBox1.Text.ToString().Trim() & "' and 密码='" & TextBox2.Text.ToString().Trim() & "'" Dim cmd As SqlCommand = New SqlCommand(sql, con) Dim reader As SqlDataReader reader = cmd.ExecuteReader() If reader.Read() = True Then Me.Hide() Form4.Show() Else MsgBox("登陆失败,请检查你的用户名,密码,登陆权限是否正确") End If End Sub逻辑说明:先用 SqlConnection 打开数据库连接,然后拼接 SQL 查询语句,用 SqlCommand 执行,SqlDataReader 读取结果。如果 reader.Read() 返回 True,说明存在匹配记录,登录成功,跳转到 Form4 查询界面;否则提示失败。
参数说明:连接字符串里的data source=XP23是数据库服务器实例名,initial catalog=books_management指定数据库,integrated security=true表示用 Windows 身份验证。这里有一个非常大的坑——连接字符串写死的是 “XP23” 这台机器,换一台电脑跑就要改。而且user id=XP23\Administrator;pwd=;配了账号但还开着集成验证,这俩是冲突的:integrated security=true 时 SQL Server 会忽略 user id/pwd。我的习惯是保留integrated security=true,删掉 user id 和 pwd,连接会更干净。
还有就是 SQL 注入。这段代码用字符串拼接的方式把 TextBox 里的值拼进 SQL,输入' or 1=1 --这类内容可以直接绕过登录验证。实训报告这么写可以理解,但你应该知道这在生产环境是大忌。后面我会在进阶章节给出参数化查询的改法。
4.3 管理员端功能:借阅、归还和查询的实现套路
管理员登录成功后会进入 Form6 图书管理界面。这个窗体里放了四个按钮:图书查询、图书借阅信息查询、图书管理、图书归还。借阅信息查询的代码非常有代表性:
Imports System.Data Imports System.Data.SqlClient Public Class Form6 Dim strcon As String = "data source=XP23;initial catalog=books_management;user id=XP23\Administrator;pwd=;integrated security=true;" Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim con As SqlConnection = New SqlConnection(strcon) con.Open() Dim selectStudent As String = "select * from borrow" Dim ds As DataSet = New DataSet() Dim da As SqlDataAdapter = New SqlDataAdapter(selectStudent, con) da.Fill(ds, "borrow") Me.DataGridView1.DataSource = ds.Tables("borrow") con.Close() End Sub End Class这段代码的逻辑是:点击按钮后打开连接,把 borrow 表所有记录查出来,用 SqlDataAdapter 填充到 DataSet,最后绑定到 DataGridView 显示。SqlDataAdapter 是断开式数据访问的核心——它先通过 SELECT 从数据库拿数据填进内存,之后即使断开连接,DataGridView 也能正常显示。DataGridView 绑定 DataTable 的操作是最省事的,不需要手动遍历逐行填充,适合快速搭界面。
借书功能的 INSERT 代码走的是字符串拼接路线:
Dim name As String = Me.TextBox3.Text Dim num As String = Me.TextBox4.Text Dim time As String = Me.TextBox5.Text Dim num2 As String = Me.TextBox6.Text Dim addclass As String = String.Format("insert into borrow values('{0}','{1}','{2}','{3}')", name, num, time, num2) Dim strcon As String = "data source=XP23;initial catalog=books_management;user id=XP23\Administrator;pwd=;integrated security=true;" Dim con As SqlConnection = New SqlConnection(strcon) con.Open() Dim cmd As SqlCommand = New SqlCommand(addclass, con) Dim result As Integer = cmd.ExecuteNonQuery() If result < 1 Then MessageBox.Show("添加失败!", "操作提示", MessageBoxButtons.OK, MessageBoxIcon.Warning) Else MessageBox.Show("添加成功!", "操作提示", MessageBoxButtons.OK, MessageBoxIcon.Information) Me.Close() End If这里用ExecuteNonQuery()执行 INSERT,返回受影响行数 result,如果小于 1 说明没插入成功。四个参数按顺序对应 borrow 表的四个字段:学号、书号、借阅时间、借阅量。不用 SqlParameter 而用 String.Format,实训演示没问题,但注意如果借阅时间输入框里带单引号,SQL 会直接语法错误。
还书功能用的是先查后删的策略:点击行时先把该行的学号和书号取出来,弹出确认框,再去 borrow 表执行 DELETE:
Dim deleteStudent As String = String.Format("DELETE FROM borrow WHERE 学号='{0}' and 书号='{1}'", stuid, stuid1) Dim con As SqlConnection = New SqlConnection(strcon) con.Open() Dim cmd As SqlCommand = New SqlCommand(deleteStudent, con) Dim result As Integer = Convert.ToInt32(cmd.ExecuteNonQuery()) con.Close()这个设计的本质是“借阅记录删除即归还”——borrow 表里留着记录表示该书在借,删掉就表示已归还。但这里有个缺陷:删的是整条记录,没有保留借阅历史。如果要统计某本书被借过多少次,这个表结构做不到。实训项目可以接受,但你应该意识到 borrow 表更适合增加一个“归还时间”字段,还书时只 UPDATE 归还时间,而不是 DELETE 整行。
5. 避坑指南:照这份报告复现时最容易翻车的五个点
5.1 连接字符串写死了机器名,换电脑必连不上
现象:把代码原样复制到另一台电脑,运行后 SqlConnection.Open() 抛异常,提示“服务器 XP23 不存在或访问被拒绝”。
原因:连接字符串里data source=XP23是报告作者当年的机器名。SQL Server 实例名跟着环境走,换机器必须改。
解决:改用data source=.\SQLEXPRESS或.(本机默认实例),保留integrated security=true,删掉 user id 和 pwd。如果你装的是 SQL Server 2019/2022 开发版,默认实例名通常是 MSSQLSERVER,连接字符串写data source=.;initial catalog=books_management;integrated security=true;即可。
5.2 student 表没有密码字段,学生登录必失败
现象:管理员登录正常,学生输入学号和密码后永远提示“登陆失败”,或者直接报“列名 '密码' 无效”。
原因:建表脚本里 student 表只有学号、姓名、性别、班级、联系电话五个字段,但 Form2 的登录 SQL 查了“密码”列。
解决:在 student 表上补一列,或者在登录代码里改成只验证学号。我建议补列,因为系统设计里学生登录必须有密码。执行alter table student add 密码 varchar(200) not null default '123456',再往表里插几条测试数据,登录就能跑通。
5.3 中文字段名和中文标点符号容易被复制出问题
现象:建表脚本执行时报语法错误,排查半天发现代码里有全角逗号,或者字段名引号不匹配。
原因:原报告的代码经过排版复制后,中文字段两侧的引号、语句末尾的逗号偶尔会被替换成全角版本。SQL Server 不认全角字符。
解决:所有标点一律切换成半角英文输入法重新敲一遍。中文字段名本身没问题,但建议先用英文别名——我就是把学号映射成stu_id来写的查询,后续程序里处理起来省心很多。
5.4 联合主键导致同一学生不能重复借同一本书
现象:学生第二次借同一本书时,INSERT 报错,提示“违反 PRIMARY KEY 约束”。
原因:borrow 表主键是(学号, 书号),同一学生借同一本书的记录只能存在一条。这在图书管理场景下意味着“续借”或“再借一本”都无法实现。
解决:如果想支持重复借阅,把主键改成自增列,学号和书号改为普通索引;如果只做简单演示,那保持联合主键也可以——借阅前先查一下是否已借,已借就提示归还后再借。报告本身没有处理这个逻辑,复现时注意。
5.5 管理员登录窗体里的“密码”列同样有隐患
现象:管理员登录有时成功有时失败,排查发现 administrator 表里有密码字段,但登录代码直接明文拼接,输入含特殊字符的密码会把 SQL 弄坏。
原因:原报告没有用参数化查询,所有用户输入直接拼接进 SQL。密码里如果带单引号、分号这类字符,轻则查询失败,重则被构造出额外语句。
解决:至少用 SqlParameter 替换拼接,下面是一个能直接替换的写法:
Dim sql As String = "select * from [student] where 学号=@id and 密码=@pwd" Dim cmd As SqlCommand = New SqlCommand(sql, con) cmd.Parameters.AddWithValue("@id", TextBox1.Text.Trim()) cmd.Parameters.AddWithValue("@pwd", TextBox2.Text.Trim()) Dim reader As SqlDataReader = cmd.ExecuteReader()参数说明:@id和@pwd是命名参数,AddWithValue 会把 TextBox 的文本作为参数传给 SQL Server,由数据库引擎处理转义,从根本上规避注入风险。
6. 把这份实训报告改成能稳定演示的系统:验证流程与改良配方
6.1 先跑通再优化:一套完整的验证路径
拿到这份 PDF 后,我建议按下面的顺序来复现,每完成一步做一次验证,不要跳步:
- 建库脚本在 SSMS 里执行,确认 books_management 数据库和五张表都存在。
- 手动往 student 表插入一条测试数据,往 books 表插入三本图书。
- 在 VS 里新建一个 VB.NET WinForms 项目,把 Form1 到相关窗体按报告里的代码敲进去。
- 先测管理员登录,能进 Form6 说明连接字符串和 administrator 表可用。
- 再测学生登录,这时大概率会遇到“列名无效”的报错——因为 student 表没有密码列,按第 5.2 节的改法补上。
- 学生查询图书、管理员借阅和归还逐项走一遍,最后在 SSMS 里查 borrow 表,确认数据变化符合预期。
验证连接是否成功,除了跑程序,还有更快的方式——在 VS 的“服务器资源管理器”里直接添加数据连接,填好服务器名和数据库名,能展开表节点就说明连接字符串没问题。
6.2 几个低成本高收益的改良动作
第一个改良是给五张表补上外键约束,这一步不用改代码,直接在 SSMS 里执行:
alter table borrow add constraint fk_borrow_student foreign key (学号) references student(学号) alter table borrow add constraint fk_borrow_books foreign key (书号) references books(书号) alter table management add constraint fk_management_admin foreign key (编号) references administrator(编号)加上外键后,删除学生或图书时如果有未归还的借阅记录,数据库会拒绝删除,避免数据不一致。对实训答辩来说,这是一个可以加分的细节——你主动考虑了数据完整性。
第二个改良是把“归还”从删除改成更新。borrow 表加一列归还时间 varchar(100) null,还书时执行:
update borrow set 归还时间 = getdate() where 学号 = @stuId and 书号 = @bookId and 归还时间 is null这样一来借阅历史被保留,你可以随时统计图书流转情况,系统从“只能演示”升级成“有点业务价值”。如果时间充裕,再加一个“图书分类统计”的可视化面板,整个实训报告的评价会上一个台阶。
第三个技巧是给 DataGridView 加只读属性。管理员端的 DataGridView 绑定查询结果后,默认情况下单元格是可以编辑的——虽然不会直接改数据库,但演示时容易被评委误操作。在窗体设计器里把 DataGridView 的ReadOnly设为True,SelectionMode设为FullRowSelect,体验会好很多。
6.3 演示前的最后一道检查
演示之前,把连接字符串统一改成相对本机的写法,并写进一个公共模块。我习惯建一个Module1.vb,里面放:
Module Module1 Public strcon As String = "data source=.;initial catalog=books_management;integrated security=true;" End Module逻辑说明:然后所有窗体的Dim strcon As String都删掉,直接用 Module1 里的全局变量。这样连接配置集中在一处,换机器只改一个地方。原报告把连接字符串复制到每个窗体里,改起来很容易漏。
有件事我想提醒你:这份资源里的代码风格是比较老的 VB.NET 写法,很多地方可以交给 ChatGPT 或 Copilot 帮你重构,但前提是你先按原样跑通一遍。没有跑通就大改,出了问题你根本分不清是环境问题还是代码问题。我拆过的实训资料里,能一次跑通的少之又少,最稳妥的做法永远是先照着原样复现、再谈优化。从那以后,我每次拿到这种实训报告,都强制自己先按原文完整搭一遍,把所有报错记录下来,再动手改——这个过程看起来绕路,实际是最快的。希望这份拆解能帮你在做图书管理系统实训时少踩几个坑。
本文还有配套的精品资源,点击获取