
简介一份完整的《通讯录管理系统数据库课程设计报告》面向互联网软件开发及数据库原理与应用课程的本科学生和需要完成同类课程设计的人。报告以湖南涉外经济学院课程设计为背景完整涵盖需求分析、概念结构设计、逻辑设计、数据库实施、运行维护等阶段详细给出数据流图、数据字典、实体属性图、局部E-R图、关系模式优化过程以及建库建表、视图和存储过程的SQL代码界面部分覆盖登录、联系人、分组、查询等模块并配有任务分配表、摘要、目录和总结。这套内容既可作为课程设计报告的写作模板也可帮助读者完整理解SQL Server与Java结合的通讯录系统从分析到实现的流程。资源为1个docx文档大小840KB目前已有74人学习下载适合用于快速搭建自己的课程设计报告框架。1. 通讯录管理系统一份能直接复现的数据库课程设计报告通讯录管理系统是数据库课程设计里出现频率最高的题目之一这份来自湖南涉外经济学院信息科学与工程学院的完整课程设计报告把 SQL Server 建库、三张核心表、视图、存储过程到 Java 界面模块全部串成一条可执行的链路适合正在做数据库原理与应用课程设计、又不知道报告怎么落笔的人直接照做。它解决的并不只是“做出一个能增删改查的通讯录”而是把需求分析、数据字典、E-R 图、范式优化、运行维护的完整流程补齐对照它写自己的报告能少走很多弯路。想快速搞定课程设计文档结构和数据库部分的新手以及需要一份完整项目做参考的老手都能在这份资料里找到对应章节。2. 需求分析与概念设计先看懂数据字典再动手2.1 功能清单决定了数据库的边界这份报告在第二章把通讯录管理系统的功能拆得很清楚用户登录、添加联系人、修改联系人、删除联系人、查询联系人、显示全部联系人外加分组信息的查询和删除。为什么先列功能清单因为数据库里建几张表、每张表放哪些字段完全由功能倒推出来。如果你只做联系人增删改查那一张联系人表就够了但一旦出现“按朋友、同学、同事分组查看”就需要额外考虑分组信息的存储方式。报告里采用的做法是把分组单独拆出来维护同时在联系人表里保留“分组类别”字段。这种设计的意图是分组既作为联系人的一个属性存在又有独立的查询入口两种使用方式互不干扰。实际开发时要注意分组和联系人之间的关系是一对多也就是一个分组下可以有多个联系人但一个联系人同一时刻只属于一个分组。2.2 数据字典是建表的直接依据报告中的数据字典部分值得细读它定义了用户名、密码、编号、姓名、性别、电话号码、E-mail、分组类别这些字段的数据类型和长度。这里有几个关键点要留意用户名用 char(10)密码用 char(10)编号用 char(10)电话号码用 varchar(50)E-mail 用 varchar(50)。char 和 varchar 的区别在于定长与变长。char(10) 不管实际存几个字符都占用 10 字节varchar(50) 按实际长度存储。对于编号这类固定长度的业务主键用 char 没问题但电话号码、E-mail 长度不确定如果也定义成 char(50)查询时末尾会带着空格Java 里做字符串匹配非常容易翻车。报告里这个设计是合理的但你在复现时可以把电话号码改成 varchar(20)E-mail 改成 varchar(50)更贴近实际生产习惯。数据字典表里的内容要对应到建表语句这是课程设计报告最容易失分的地方。不少同学写报告时需求分析写一套建表语句写另一套字段对不上答辩时一问就露馅。正确做法是先列数据字典再照着数据字典写建表 SQL保证每个数据项都能在表结构里找到归属。2.3 E-R 图实体与属性怎么对应表报告第三章定义了三个核心实体用户登录信息用户名、密码、联系人详细信息编号、姓名、性别、电话号码、出生日期、E-mail、分组类别、分组信息编号、姓名。实体间的联系是一个用户拥有多个联系人一个联系人属于一个分组。从 E-R 图到表的转换规则很直接每个实体对应一张表实体属性对应表的字段实体间的“一对多”联系通过在外键方添加关联字段实现。所以这里至少有三张表用户表、联系人表、分组相关表。但报告里把分组拆成了“朋友分组表”和“同学分组表”两张这个设计可以讨论后面逻辑设计章节会展开讲它的问题和优化空间。2.4 数据流图在报告答辩中的作用数据流图在课程设计答辩中经常被问到因为它展示了数据在系统里怎么流动。报告里的顶层数据流图、0 层数据流图分别对应“用户登录系统”和“登录后对联系人进行增删改查”两个层次。复现时不用把图画得特别复杂能说清三层就行顶层是用户与系统之间的数据交互0 层是系统内部的登录模块、联系人模块、分组模块之间的数据流再往下每个模块还能继续细分。答辩老师主要考察你是否理解数据从哪里来、经过什么处理、存到哪里去而不是画得有多专业。3. 逻辑结构设计三张表怎么从 E-R 图变成关系模式3.1 关系模式转化与主外键确定报告第四章把 E-R 图转化成了关系模式这一步是数据库设计中最核心的环节。转化出的关系模式包括联系人信息编号、姓名、性别、出生日期、电话号码、E-mail、地址、分组类别主键为编号朋友分组信息朋友编号、姓名外键为朋友编号同学分组信息同学编号、姓名外键为同学编号。主键的作用是唯一标识一条记录联系人编号在数据字典里定义为 char(10)正好可以作为主键。这里有个容易被忽略的问题朋友分组表和同学分组表的外键都指向联系人编号意味着分组表里的记录必须先在联系人表里存在。这就是外键约束它能防止数据不一致但也带来后续删除操作时顺序上的限制后面避坑章节会专门讲。3.2 函数依赖与范式判断为什么这份设计能达到第三范式函数依赖的概念在答辩时基本必问。报告里明确指出联系人信息表中姓名、性别、出生日期、电话号码、E-mail、地址、分组类别都依赖于编号分组表中姓名依赖于编号。这就构成了“非主属性完全依赖于主键”的第二范式条件。判断是否达到第三范式要看是否存在传递依赖。以联系人表为例编号决定姓名姓名决定分组类别但分组类别并不反过来决定编号也就是说分组类别不直接依赖编号而是依赖姓名但姓名本身又完全依赖编号这里存在传递依赖的嫌疑。报告里把分组类别定义为直接依赖编号同时通过“分组类别”这个字段在联系人表和分组表之间建立联系避免了传递依赖的出现因此判断为第三范式。实际答辩中老师可能会追问“如果联系人表里同时有编号、分组编号、分组名称三个字段是否满足第三范式”这种变体问题考查的就是传递依赖的判断能力。答案是不满足因为分组名称依赖于分组编号而分组编号依赖于联系人编号存在传递依赖需要把分组信息单独拆成一张表。3.3 关系模式优化拆表还是不拆表报告里一个值得讨论的设计是把分组信息拆成了“朋友分组表”和“同学分组表”。这个设计的出发点可能是为了查询方便从“朋友分组界面”和“同学分组界面”直接对应表。但从关系数据库规范化的角度看这不是最佳选择——如果以后要加一个“同事分组”就得新建一张同事分组表表结构完全一样属于重复设计。更合理的做法是建一张分组表结构是分组编号、分组名称、联系人编号通过分组名称区分朋友、同学、同事。但如果你是按这份报告的思路交作业拆表也能自圆其说因为报告明确给出了“不同分组界面查询不同分组表”的设计理由答辩时能把逻辑讲通就行。如果想让设计更规范可以在报告结论里加一句“进一步优化方向是合并分组表增加分组类别字段区分”这反而能体现你对范式理解的深度。3.4 表结构字段设计对照报告中的表结构字段可以用下面的表来梳理建表时直接照此执行表名字段类型长度约束用户表用户名char10主键用户表密码char10非空联系人表编号char10主键联系人表姓名char10非空联系人表性别char2默认值联系人表出生日期char20可空联系人表电话号码varchar50可空联系人表E-mailvarchar50可空联系人表分组类别varchar20非空朋友分组表朋友编号char10主键朋友分组表姓名char10非空同学分组表同学编号char10主键同学分组表姓名char10非空这张表可以直接抄进自己的报告里作为逻辑设计章节的表结构说明。要注意把“数据类型”“是否为空”“约束”三列写完整这是评分的硬指标。4. SQL Server 库表实施建库、三张核心表、视图与存储过程4.1 建库脚本文件路径是第一个坑点报告第五章给出了完整的建库 SQL这个脚本是整份资料里最实用的部分直接复制就能在 SQL Server 里建出一个完整的通讯录数据库。建库代码需要指定主数据文件和日志文件的路径、初始大小、最大大小和文件增长策略create database [通讯录管理系统] on primary ( name 通讯录管理系统, filename D:\数据库\通讯录管理系统.mdf, size 10MB, maxsize 100MB, filegrowth 20% ) log on ( name 通讯录管理系统_log, filename D:\数据库\通讯录管理系统_log.ldf, size 5MB, maxsize 50MB, filegrowth 10% ) go这段脚本的关键参数size 指定数据库文件初始大小maxsize 限制文件增长上限filegrowth 设定自动增长的幅度。如果业务数据量大把 filegrowth 的百分比调高一点能减少频繁扩容带来的性能损耗。实际执行时最常见的报错是“路径不存在”——如果 D 盘没有“数据库”这个文件夹SQL Server 不会自动创建目录必须先建目录再执行脚本。建议第一次练习时把路径改成自己机器上确实存在的目录比如 D:\SQLData\免得被这个细节卡住。4.2 建表顺序有讲究先建主表还是先建从表建表顺序直接影响外键能否成功创建。正确顺序是先建没有外键依赖的表再建被依赖的表。在这套设计里联系人表是核心表用户表和分组表都依赖它所以先建联系人表再建分组表。用户表没有外键放在哪个位置都可以习惯上放在第一位use [通讯录管理系统] go -- 1. 先建用户表 create table [用户] ( 用户名 char(10) not null primary key, 密码 char(10) not null ) go -- 2. 再建联系人表 create table [联系人] ( 编号 char(10) not null primary key, 姓名 char(10) not null, 性别 char(2) not null default 男, 出生日期 char(20) null, 电话号码 varchar(50) null, E_mail varchar(50) null, 分组类别 varchar(20) not null ) go -- 3. 最后建分组表 create table [朋友分组] ( 朋友编号 char(10) not null primary key, 姓名 char(10) not null ) go create table [同学分组] ( 同学编号 char(10) not null primary key, 姓名 char(10) not null ) go以上建表语句里的 not null 表示字段不能为空primary key 定义主键default 设置默认值。联系人表的性别字段设置默认值为“男”添加数据时如果不填性别系统会自动填入“男”。这里要注意 E_mail 字段名不能写成 E-mail因为减号在 SQL Server 标识符里会被解析成减号导致语法错误这是很多同学第一次跑这段代码时翻车的点。4.3 视图把常用的分组查询固化下来报告里提到视图创建代码但没有给出完整语句。视图的本质是一条预编译的查询语句把常用的查询逻辑固化成虚拟表。对于通讯录系统最常用的视图就是“按分组类别查看联系人”这个场景用视图非常合适create view v_同学联系人 as select 编号, 姓名, 性别, 电话号码, E_mail, 分组类别 from 联系人 where 分组类别 同学 with check option go视图里的 with check option 是一个很容易被忽略的细节。它保证了对视图的插入、修改操作必须满足视图定义的 where 条件。也就是说通过 v_同学联系人 视图修改数据时不能把某个联系人的分组类别改成“朋友”否则数据库会报错。这个特性在权限控制场景下特别有用比如给一个只负责同学分组数据的工作人员开放视图权限他只能操作分组类别为“同学”的数据。视图的另一大好处是简化 Java 端的查询逻辑。Java 程序里可以直接select * from v_同学联系人不用在代码里拼接 where 条件查询语句的可读性大幅提升。4.4 存储过程把增删改查封装成数据库接口存储过程在这个项目里的作用是把事务性的数据库操作封装起来。为什么不用 Java 直接写 SQL因为存储过程在数据库端预编译执行效率高于每次从 Java 端发送的 SQL 语句而且业务逻辑修改时只需要改数据库端Java 代码不用重新部署。以查询联系人和删除联系人两个核心操作为例存储过程的写法如下-- 按关键字模糊查询联系人 create procedure proc_查询联系人 关键字 varchar(50) as begin select 编号, 姓名, 性别, 电话号码, E_mail, 分组类别 from 联系人 where 编号 like % 关键字 % or 姓名 like % 关键字 % or 电话号码 like % 关键字 % end go -- 按编号删除联系人 create procedure proc_删除联系人 编号 char(10) as begin delete from 联系人 where 编号 编号 select 删除成功 as 提示 end go参数 关键字 和 编号 前面的 符号是 SQL Server 存储过程参数的固定语法。存储过程中的 % 是 SQL 模糊匹配的通配符表示任意长度的任意字符。like 配合 % 可以实现“输入姓名的一部分就能查到完整信息”的搜索效果。执行存储过程用 execute 关键字execute proc_查询联系人 关键字 张; execute proc_删除联系人 编号 10001;这段脚本值得注意的地方模糊查询里用的是% 关键字 %而不是% || 关键字之类的写法因为 SQL Server 的字符串拼接符号就是加号。Java 端调用存储过程时用 CallableStatement代码会清爽很多也算给 Java 部分的实现提前铺了路。5. 常见问题与避坑这份报告里没写清楚的五个注意点5.1 建库失败报错“路径不存在”现象执行 create database 脚本时SQL Server 报错找不到路径数据库文件创建失败。原因脚本里写的是filename D:\数据库\通讯录管理系统.mdf但 D 盘下根本没有“数据库”这个文件夹而 SQL Server 不会自动创建目录。解决先在操作系统中手动创建D:\数据库文件夹或者把 filename 改成自己机器上真实存在的路径。我一般在练习时会建立一个独立的D:\SQLData目录专门存放课程设计的数据库文件便于管理和清理。此外注意脚本里的反斜杠\在 SQL Server 字符串里不需要转义但如果是 Java 代码里拼接路径字符串需要写成\\。5.2 中文字段名的编码坑现象表结构里中文表名和字段名在查询分析器里一切正常但 Java 程序通过 JDBC 连接后查询报错或者查到的是乱码。原因SQL Server 默认排序规则可能不支持中文或者 Java 连接字符串没有指定正确的编码参数。另外SQL Server 允许中文标识符但连接字符串里的 databaseName 参数传中文库名时如果 JDBC URL 没做 URL 编码也会出错。解决连接字符串里加上characterEncodingUTF-8查询分析器里执行select name from sys.databases检查库名编码。更稳妥的做法是建库时用英文库名比如AddressBookDB表名和字段名也用英文或拼音如Users、Contacts、GroupTypeJava 端取值后显示层再做中文映射。这份报告用中文命名是为了教学设计直观但实盘开发时中文标识符带来的兼容性问题远大于可读性收益。5.3 删除联系人时外键约束冲突现象先删了联系人表里的某条记录再去删朋友分组表里对应的记录时或者反过来操作时SQL Server 报外键约束冲突删除失败。原因分组表的外键指向联系人表的主键只要联系人还在分组表里引用它的记录就不能被删除。如果不先删掉分组表里对应的记录直接删联系人数据库会拒绝执行。解决删除时先删子表数据再删主表数据。要么手动按顺序执行要么建表时在外键上设置on delete cascade级联删除这样删除联系人时分组表里对应的记录会自动删除。报告原文没有提到级联删除复现时如果遇到这个报错可以直接在删除联系人前先执行delete from 朋友分组 where 朋友编号 xxx或者修改外键定义。5.4 视图更新报错“本次更新未影响任何行”现象Java 端通过视图更新联系人分组类别执行成功但返回影响行数为 0或者报错“with check option 验证失败”。原因视图定义了where 分组类别 同学且带with check option此时通过视图只能修改分组类别为“同学”的记录如果把某条记录的分组改成“朋友”数据库认为修改后的记录不符合视图定义条件直接拒绝。解决分情况处理。如果在 Java 端想实现“把联系人从同学组移到朋友组”应该直接操作联系人表而不是通过分组视图。课程设计答辩时如果有老师问“为什么视图不能改分组”能答出 with check option 的原理是一个很大的加分项。5.5 Java 连不上 SQL Server驱动版本与端口问题现象JDBC 连接 SQL Server 时抛ClassNotFoundException或Connection refused。原因前者是机器上没有装对应版本的 JDBC 驱动 jar 包后者是 SQL Server 默认没有开启 TCP/IP 协议或者服务端口不是默认的 1433。解决把 sqljdbc4.jar 放到项目的 WEB-INF/lib 目录下在环境变量里配置 classpath。SQL Server 配置管理器里把 TCP/IP 启用端口要确认是 1433。还有一个小坑SQL Server 的登录验证模式要改成“SQL Server 和 Windows 身份验证模式”然后创建带密码的登录账户否则 Java 端用jdbc:sqlserver://localhost:1433;databaseNameAddressBookDB连的时候会出现用户名密码错误提示。6. 拿到资料后的高效复现顺序先跑库再写界面这份报告的正确打开方式不是从第一页开始读到最后一页而是先做数据库验证再做界面还原。我拿到资料后的操作流程通常是这样的供你参考。第一步花十五分钟把数据库脚本跑通。打开 SQL Server Management Studio新建查询窗口把第 4 章的建库、建表、视图、存储过程脚本依次执行执行完看一眼对象资源管理器如果能看到“通讯录管理系统”数据库、三张表、一个视图、两个存储过程数据库部分就验证成功了。第二步准备测试数据。往联系人表插入五六条记录覆盖朋友、同学、同事三种分组再往两张分组表插入对应数据。这一步不能跳过因为没有测试数据就无法验证视图和存储过程的查询逻辑后面写 Java 界面时也没有数据可展示。insert into 联系人 (编号, 姓名, 性别, 电话号码, 分组类别) values (10001, 张三, 男, 13800138000, 同学); insert into 联系人 (编号, 姓名, 性别, 电话号码, 分组类别) values (10002, 李四, 女, 13900139000, 朋友); insert into 联系人 (编号, 姓名, 性别, 电话号码, 分组类别) values (10003, 王五, 男, 13700137000, 同事);第三步逐个验证存储过程。执行execute proc_查询联系人 关键字 张确认能查到张三执行execute proc_删除联系人 编号 10003再查询确认王五已被删除。存储过程验证通过后Java 界面的 DAO 层只是做一层调用封装难度大大降低。最后一步是写界面。报告里的 Java 部分是 Swing 图形界面登录模块、联系人界面、分组界面、增删改查界面都有截图。复现时不需要把界面做得和报告一模一样用 Java Swing 搭一个简单的主窗口左侧放按钮、右侧放联系人表格即可。关键是把 DAO 层里的 SQL 替换成上面的存储过程调用例如用CallableStatement调用proc_查询联系人这样数据库端和 Java 端的分工就和报告的设计意图一致了。从那以后我每次拿到一份课程设计报告都不会先急着写代码而是强制自己先走一遍这个流程建库脚本先跑通视图和存储过程再验证一次最后才碰界面代码。前后不超过半小时但能规避掉交作业前最尴尬的数据库连不上、存储过程执行失败这类问题。希望这份通讯录管理系统的课程设计思路能帮到你尤其是正在为数据库课程设计头疼的同学按这个顺序复现效率会明显不一样。本文还有配套的精品资源点击获取