
简介这份数据库课程设计文档面向高校数据库系统及应用课程的选课学生与指导教师以“校园二手交易系统”为完整案例解决从需求调研到数据库落地缺乏规范范例的问题。压缩包内仅1个doc文件约1.72MB内容为一份完整的实验报告涵盖需求说明书、概念E-R模型、逻辑模型规范化、物理模型设计以及视图、触发器、存储过程、安全与恢复方案等数据库对象设计并附系统实现与个人工作总结。报告还记录了使用PowerDesigner建模、SQL Server与Visual Studio开发工具的具体过程以及小组分工与自评表可作为课程设计报告的撰写模板与评分参考。目前已有1572人学习下载适合需要参照完整设计流程、快速搭建校园二手交易数据库并完成规范报告的学生与教师使用。1. 从一份“数据库课程设计(5).doc”说起它到底要你交什么如果你手里正躺着一份名为“数据库课程设计(5).doc”的任务书大概率你面对的不是一道 SQL 题而是一整套从需求分析、概念设计、逻辑设计到物理实现、前端联调的完整交付物。它通常出现在计算机相关专业的期末或短学期要求你选一个业务场景图书管理、学生选课、超市进销存、医院挂号都行用 SQL Server 建库建表用 PowerDesigner 画 CDM/PDM再用 Visual Studio 写一个能跑通增删改查的桌面程序最后把过程写成文档。这份文档就是你的“验收凭证”老师看的是你有没有把数据库设计的方法论走一遍而不是看你界面多花哨。它适合谁适合已经学过《数据库系统原理》、能写基本 SELECT但没独立做过一个完整项目的人。你不需要精通 C#也不需要把界面做得像商业软件但你必须能说清楚为什么这么分表、主外键怎么定、范式有没有过度、索引加在哪、并发怎么处理。这篇笔记就按“需求→建模→建库→写程序→排错”的真实顺序把每个环节的可复现步骤和参数讲透让你能照着做出一份能过验收、也能自己讲明白的课程设计。2. 需求与概念建模用 PowerDesigner 把业务画成 CDM2.1 先定业务边界再谈表结构很多人一上来就打开 SQL Server 建表结果做到一半发现字段不够、关系对不上只能删库重来。血泪经验是先写清楚业务规则再画图最后才建表。以“学生选课系统”为例你需要先回答几个问题一个学生能选几门课一门课有容量上限吗选课记录要不要保留退课历史成绩是选课时录还是期末统一录这些规则直接决定表的数量和字段。我一般会拿一张纸左边列“名词”学生、课程、教师、班级右边列“动词”选修、讲授、属于。名词大概率是实体动词大概率是关系。比如“学生选修课程”是多对多必须拆出一张中间表“教师讲授课程”如果一门课只有一个老师就是一对多外键放在课程表即可。这一步不做后面 PowerDesigner 画出来的图一定是错的。2.2 PowerDesigner 建 CDM 的具体操作打开 PowerDesignerFile → New Model → Model types → Conceptual Data Model语言选 Chinese然后开始画。实体用 Entity关系用 Relationship。下面是一个选课系统 CDM 的核心实体定义你可以直接照着填实体名属性标识符说明学生学号、姓名、性别、班级学号学号唯一课程课程号、课程名、学分、容量课程号课程号唯一教师工号、姓名、职称工号工号唯一选课学号、课程号、成绩、选课时间学号课程号联合主键画关系时注意学生与选课是一对多课程与选课也是一对多选课实体承载多对多关系。教师与课程如果是一对多就在课程实体里加“工号”作为外键属性。PowerDesigner 里设置关系基数的位置在 Relationship 属性 → Cardinality选 One-to-Many 或 Many-to-Many。很多人在这里翻车把多对多直接画成两个实体之间的 Many-to-Many结果生成 PDM 时 PowerDesigner 会自动帮你建中间表但字段名不可控后期改起来很麻烦。建议手动建中间实体命名规范用“主表_从表”或业务动词比如“学生_选课”。2.3 从 CDM 生成 PDM 的关键配置CDM 画完后Tools → Generate Physical Data ModelDBMS 选 Microsoft SQL Server 2012或你实际安装的版本。生成前点 Options重点看两个地方一是“Name to Code”转换规则建议把中文名转成英文或拼音否则建表时字段名全是中文写 SQL 要加方括号容易出错二是主键生成策略选 Identity 还是 Manual学生表用 Identity 自增没问题但选课表的联合主键不能自增要手动指定。生成 PDM 后双击表可以改字段类型。常见映射CDM 的“字符串”对应 varchar(n) 或 nvarchar(n)中文用 nvarchar“整数”对应 int“日期”对应 datetime 或 date。学分可以用 decimal(3,1)成绩用 decimal(5,2)。容量用 int。这里有个细节nvarchar 的长度如果超过 4000 会变成 nvarchar(max)索引和排序会受影响所以姓名、课程名这类字段给 50 到 100 足够。3. 物理落地在 SQL Server 里建库建表并灌入测试数据3.1 用 PDM 生成建表脚本并执行PowerDesigner 的 PDM 可以直接生成 SQL 脚本Database → Generate Database选好输出路径勾选“Generate CREATE TABLE”“Generate PRIMARY KEY”“Generate FOREIGN KEY”。生成的脚本里会有 GO 语句这是 SQL Server 的批处理分隔符用 SSMS 执行时没问题但用 JDBC 或 ADO.NET 执行时要按 GO 拆分。我一般会把脚本里的数据库名改成自己的比如USE [CourseDesign]然后先建库再建表。如果你不想用 PowerDesigner 生成也可以手写。下面是一段可直接在 SSMS 里跑的核心建表脚本包含学生、课程、选课三张表-- 创建数据库 CREATE DATABASE CourseDesign; GO USE CourseDesign; GO -- 学生表 CREATE TABLE Student ( StudentID VARCHAR(12) PRIMARY KEY, -- 学号主键 Name NVARCHAR(50) NOT NULL, -- 姓名 Gender NCHAR(1) CHECK (Gender IN (男,女)), ClassName NVARCHAR(50) ); -- 课程表 CREATE TABLE Course ( CourseID VARCHAR(10) PRIMARY KEY, -- 课程号 CourseName NVARCHAR(100) NOT NULL, Credit DECIMAL(3,1) CHECK (Credit 0), Capacity INT DEFAULT 60, TeacherID VARCHAR(10) ); -- 选课表联合主键 CREATE TABLE Enrollment ( StudentID VARCHAR(12) NOT NULL, CourseID VARCHAR(10) NOT NULL, Score DECIMAL(5,2) NULL, EnrollTime DATETIME DEFAULT GETDATE(), CONSTRAINT PK_Enrollment PRIMARY KEY (StudentID, CourseID), CONSTRAINT FK_Enroll_Student FOREIGN KEY (StudentID) REFERENCES Student(StudentID), CONSTRAINT FK_Enroll_Course FOREIGN KEY (CourseID) REFERENCES Course(CourseID) );逻辑说明StudentID 用 VARCHAR 而不是 INT因为学号可能带字母或前导零Gender 用 CHECK 约束限制取值Enrollment 的联合主键保证一个学生不能重复选同一门课外键保证引用完整性。参数上Capacity 默认 60Credit 用 DECIMAL(3,1) 可以存 3.5 这样的学分Score 用 DECIMAL(5,2) 能存 100.00。3.2 灌测试数据的三个原则测试数据不是随便 INSERT 几条就行。第一覆盖边界选课人数要有一条刚好等于容量、一条超过容量如果业务允许、一条成绩为 NULL。第二保持引用完整先插 Student 和 Course再插 Enrollment否则外键报错。第三数据量适中学生 20 到 50 条课程 10 到 20 条选课 100 条左右足够你测试查询和分页。批量插入可以用下面的脚本注意用事务包起来出错能回滚BEGIN TRANSACTION; INSERT INTO Student (StudentID, Name, Gender, ClassName) VALUES (2023001, N张三, N男, N计算机2301), (2023002, N李四, N女, N计算机2301), (2023003, N王五, N男, N计算机2302); INSERT INTO Course (CourseID, CourseName, Credit, Capacity, TeacherID) VALUES (C001, N数据库原理, 4.0, 60, T001), (C002, N数据结构, 3.5, 50, T002), (C003, N操作系统, 4.0, 55, T003); INSERT INTO Enrollment (StudentID, CourseID, Score) VALUES (2023001, C001, 88.5), (2023001, C002, NULL), (2023002, C001, 92.0); COMMIT;执行后可以用SELECT * FROM Enrollment验证。如果报外键冲突检查 Student 和 Course 里有没有对应的主键值。3.3 索引加在哪三个必调参数课程设计里索引不是越多越好。我一般只加三类主键索引自动生成、外键索引、高频查询字段索引。外键索引是因为 SQL Server 不会自动为外键建索引而连接查询时外键列经常出现在 JOIN 条件里。比如 Enrollment 的 StudentID 和 CourseID 上各建一个非聚集索引CREATE INDEX IX_Enrollment_Student ON Enrollment(StudentID); CREATE INDEX IX_Enrollment_Course ON Enrollment(CourseID);高频查询字段比如 CourseName如果经常按课程名模糊查询可以建索引但 LIKE %数据库% 这种前置通配符用不上索引要改成 LIKE 数据库% 或者用全文索引。参数上填充因子默认 0 或 100 都行课程设计数据量小不用调。如果查询慢先用 SET STATISTICS IO ON 看逻辑读再决定加不加索引。4. Visual Studio 端用 WinForms 把增删改查串起来4.1 连接字符串与数据访问层在 Visual Studio 里新建 Windows Forms App (.NET Framework)项目名随意。先建一个 DataAccess 类把连接字符串写进去。连接字符串的格式string connStr Data Source.;Initial CatalogCourseDesign;Integrated SecurityTrue;Data Source 用点表示本机默认实例如果装了命名实例就写.\SQLEXPRESS。Integrated SecurityTrue 表示用 Windows 身份验证不用输账号密码。如果你用 SQL Server 身份验证改成User IDsa;Password你的密码。注意密码不要硬编码在代码里提交到仓库课程设计里至少放到 App.config 的 connectionStrings 节点。数据访问层我一般写一个通用方法用 SqlConnection、SqlCommand、SqlDataAdapter 三件套。查询返回 DataTable增删改返回受影响行数。下面是一个查询选课信息的示例public DataTable GetEnrollments() { DataTable dt new DataTable(); string sql SELECT s.StudentID, s.Name, c.CourseName, e.Score FROM Enrollment e JOIN Student s ON e.StudentID s.StudentID JOIN Course c ON e.CourseID c.CourseID; using (SqlConnection conn new SqlConnection(connStr)) using (SqlCommand cmd new SqlCommand(sql, conn)) using (SqlDataAdapter adapter new SqlDataAdapter(cmd)) { conn.Open(); adapter.Fill(dt); } return dt; }逻辑说明using 保证连接和命令对象释放JOIN 把三张表连起来界面上直接显示学生姓名和课程名而不是一堆 ID。参数上如果查询要带条件用 SqlParameter 而不是字符串拼接防止 SQL 注入。比如按学号查cmd.Parameters.AddWithValue(sid, sid);SQL 里写WHERE s.StudentID sid。4.2 用 DataGridView 绑定数据并实现增删改WinForms 里最快的方式是拖一个 DataGridView然后代码里绑定 DataTable。增删改可以用 SqlCommandBuilder 自动生成但课程设计里建议手写因为老师会问“你怎么实现的”。下面是一个插入选课记录的按钮事件private void btnEnroll_Click(object sender, EventArgs e) { string sql INSERT INTO Enrollment (StudentID, CourseID) VALUES (sid, cid); using (SqlConnection conn new SqlConnection(connStr)) using (SqlCommand cmd new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue(sid, txtStudentID.Text.Trim()); cmd.Parameters.AddWithValue(cid, txtCourseID.Text.Trim()); conn.Open(); int rows cmd.ExecuteNonQuery(); MessageBox.Show(rows 0 ? 选课成功 : 选课失败); } RefreshGrid(); // 重新查询并绑定 }参数说明sid 和 cid 从文本框获取Trim() 去掉空格。ExecuteNonQuery 返回受影响行数大于 0 表示成功。如果主键冲突重复选课会抛 SqlException可以用 try-catch 捕获并提示“该课程已选”。删除和修改类似把 SQL 换成 DELETE 或 UPDATE注意 WHERE 条件一定要带主键否则全表更新。4.3 事务处理选课与容量扣减要一起成功如果业务要求选课时课程容量减一这两步必须在一个事务里。否则选课记录插入了但容量没扣或者容量扣了但记录没插数据就不一致。用 SqlTransactionusing (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); SqlTransaction tx conn.BeginTransaction(); try { string sql1 UPDATE Course SET Capacity Capacity - 1 WHERE CourseID cid AND Capacity 0; SqlCommand cmd1 new SqlCommand(sql1, conn, tx); cmd1.Parameters.AddWithValue(cid, cid); int affected cmd1.ExecuteNonQuery(); if (affected 0) throw new Exception(容量不足); string sql2 INSERT INTO Enrollment (StudentID, CourseID) VALUES (sid, cid); SqlCommand cmd2 new SqlCommand(sql2, conn, tx); cmd2.Parameters.AddWithValue(sid, sid); cmd2.Parameters.AddWithValue(cid, cid); cmd2.ExecuteNonQuery(); tx.Commit(); } catch { tx.Rollback(); throw; } }逻辑说明先更新容量如果 affected 为 0 说明容量不足或课程不存在抛异常触发回滚再插入选课记录两步都成功才 Commit。参数上Capacity 0是乐观锁的简单实现防止超选。如果并发高可以加UPDLOCK提示但课程设计里这样够用。5. 避坑与排查课程设计里最容易翻车的五件事5.1 现象PowerDesigner 生成 PDM 后字段全变拼音SQL 里全是方括号原因CDM 里用了中文属性名生成 PDM 时 Name to Code 转换规则没配好默认把中文转成拼音或乱码。解决在 CDM 阶段就把 Name 写成英文或者生成 PDM 后手动改 Code 列。更省事的办法是 Tools → Model Options → Naming Convention把 Code 的转换规则设为“取 Name 的英文”但前提是 Name 本身是英文。如果已经生成错了在 PDM 里全选表右键 → 重命名批量改 Code。5.2 现象Visual Studio 连接 SQL Server 报“未找到或无法访问服务器”原因连接字符串里的 Data Source 写错或者 SQL Server 的 TCP/IP 协议没启用或者 Windows 防火墙拦了 1433 端口。解决先确认 SQL Server 服务在运行services.msc 里看 SQL Server (MSSQLSERVER) 或 SQL Server (SQLEXPRESS)。然后打开 SQL Server 配置管理器SQL Server 网络配置 → 实例的协议 → TCP/IP 启用IP 地址里 IPAll 的 TCP 端口设为 1433。最后在连接字符串里用Data Source127.0.0.1,1433或Data Source.\SQLEXPRESS。如果还不行关掉防火墙试一次确认是防火墙问题再放行端口。5.3 现象插入中文变成问号或者查询中文条件查不到原因数据库排序规则不是中文或者字段类型用了 varchar 而不是 nvarchar或者连接字符串没加 Character Set。解决建库时指定COLLATE Chinese_PRC_CI_AS字段用 nvarchar插入时字符串前加 N比如N张三。C# 里 SqlParameter 会自动处理 Unicode不用额外设置。如果已经建了 varchar 字段用 ALTER TABLE 改成 nvarchar但注意长度会翻倍原来 varchar(50) 改成 nvarchar(50) 能存 50 个中文字符够用。5.4 现象DataGridView 绑定后修改单元格数据库没更新原因DataGridView 只是显示 DataTableDataTable 是内存副本不自动回写数据库。解决要么用 SqlCommandBuilder 配合 DataAdapter.Update要么在 CellEndEdit 事件里手动写 UPDATE 语句。我一般用手动方式因为可控。在 CellEndEdit 里拿到行索引和列名拼 SQL 更新注意用主键做 WHERE 条件。如果主键也允许改要先删后插但课程设计里主键一般不让改。5.5 现象选课人数超过容量但程序没拦住原因只在界面上判断了容量没在数据库层做约束或者事务里没加Capacity 0条件。解决在 UPDATE 语句里加AND Capacity 0根据受影响行数判断是否继续。另外可以在 Course 表上加 CHECK 约束Capacity 0但 CHECK 不能跨表所以选课时的容量扣减必须在事务里做。如果并发选课用UPDATE Course SET Capacity Capacity - 1 WHERE CourseID cid AND Capacity 0这种原子操作不要先 SELECT 再 UPDATE。6. 进阶技巧用视图和存储过程把复杂查询藏起来课程设计做到后期老师可能会问“如果我要查每个学生的总学分和平均分你怎么做”。这时候如果写一堆 JOIN 和 GROUP BY 在 C# 里代码会很难看。更好的做法是在 SQL Server 里建视图和存储过程Visual Studio 只负责调用。视图适合固定查询存储过程适合带参数的动态查询。先看一个视图统计每个学生的选课门数、总学分和平均分CREATE VIEW v_StudentSummary AS SELECT s.StudentID, s.Name, COUNT(e.CourseID) AS CourseCount, ISNULL(SUM(c.Credit), 0) AS TotalCredit, ISNULL(AVG(e.Score), 0) AS AvgScore FROM Student s LEFT JOIN Enrollment e ON s.StudentID e.StudentID LEFT JOIN Course c ON e.CourseID c.CourseID GROUP BY s.StudentID, s.Name;逻辑说明用 LEFT JOIN 保证没选课的学生也显示COUNT 和 SUM 对 NULL 的处理用 ISNULL 兜底。参数上AVG 会自动忽略 NULL所以没成绩的课不计入平均分这符合业务逻辑。建好后在 C# 里SELECT * FROM v_StudentSummary就能直接绑定 DataGridView。再看一个存储过程按课程号查选课名单支持分页CREATE PROCEDURE sp_GetEnrollmentByCourse CourseID VARCHAR(10), PageIndex INT 1, PageSize INT 10 AS BEGIN SELECT s.StudentID, s.Name, e.Score FROM Enrollment e JOIN Student s ON e.StudentID s.StudentID WHERE e.CourseID CourseID ORDER BY s.StudentID OFFSET (PageIndex - 1) * PageSize ROWS FETCH NEXT PageSize ROWS ONLY; END参数说明PageIndex 从 1 开始PageSize 每页条数。OFFSET-FETCH 是 SQL Server 2012 及以上支持的语法如果你用的是 2008 R2要用 ROW_NUMBER() 改写。调用时在 C# 里用 SqlCommand 的 CommandType.StoredProcedure参数用 AddWithValue 传。这样前端代码只有一行调用复杂逻辑全在数据库里老师一看就知道你懂分层。最后一个技巧用数据库关系图做验收演示。在 SSMS 里右键 Database Diagrams → New Diagram把三张表拖进去外键关系会自动画出来。演示的时候直接展示这个图比翻代码快得多。我习惯在课程设计最后一天把建库脚本、PowerDesigner 的 CDM/PDM 文件、Visual Studio 解决方案、数据库关系图截图打包到一个文件夹命名用“学号_姓名_数据库课程设计”。这样交作业的时候不会漏东西答辩的时候也能快速定位到每个环节。希望帮到你。本文还有配套的精品资源点击获取