《数据库课程设计--在线考试系统.doc》由会员分享,可在线阅读,更多相关《数据库课程设计--在线考试系统.doc(21页珍藏版)》请在三一办公上搜索。
1、精选优质文档-倾情为你奉上 成绩:_数据库原理及应用课程设计课题 在线考试系统 班级 计06-7 组长 栾习文 组员 栾习文 2008 年 12 月 22日2009 年 1 月 4 日 在线考试系统1 绪论随着标准化考试的日益普及,在各种考试中越来越多地采用了计算机考试的方式。相对于传统的卷面考试而言,由于传统的卷面考试从出题印刷到下发试卷等环节需要较长的时间,接触的人员相对较多,因而在保密方面具有一定的困难。而计算机考试系统采用试题库方式提供试题来源,考前无任何成套试卷,考试时考卷由计算机现场随机生成,各考生试卷不完全相同,从而避免了互相参看等作弊现象或不公平成绩的出现。同时也可考后即可获得
2、成绩,省去了人力评卷的麻烦和弊端。2 需求说明对考生而言,分为五个考试状态:待考、就绪、考试中、结束、缺考。考生用准考证号登录考试网站,然后验证考生信息是否一致,如果一致就会停留在考生须知界面,处于就绪状态。所有考生等待服务器发送统一命令分发试卷并同时进入考试中状态。在开考后20分钟后考生仍未到场,考生状态会自动设置为“缺考”,不能参加此次考试。考试过程中可自由答题(可随时定位到每一题)。如果有考生信息不一致的情况,可上报管理员,经审核后进行修改。考生考完试点击“交卷”,经确认后交卷。考后即可查看考试分数。在到达考试时间后,服务器会自动给未交卷的考生结束考试,并可同时给所有考生评卷得出分数。对
3、管理员而言,可以更改数据库的所有内容,可添加、查询、修改、删除考生的信息,设置考试的相关内容。可有选择地录入试题,为题目分类并自动在正确答案表里插入相应的标准答案。开考前服务器可自动为每考生随机生成试卷。考生号由管理员统一设置。服务器会根据考试时间来自动设置考生的考试状态。到达考试时间后,服务器可同时让所有在线考生进入答题阶段。在考试过程中,自动为考生保存考试答案。也可以查看所有考生的在线考试情况。同时也可为出现异常的考生延时等详细功能。考试全部结束后,服务器会备份所有考生信息和答题情况,并给所有考生评卷并生成所有考试成绩表,以便考生查分。3 概念模型设计针对以上的功能分析,对数据库的设计做了
4、以下分析。考虑到在线考试的特殊要求,数据库的设计应该包含以下信息:考生的基本信息用来在考生登陆时进行核对验证,防止考生信息录错的情况。考生考试的基本信息用来控制考试时间和考生的考试状态,统计在线考生和缺考情况,同时也方便服务器统一发送命令,给所有考生同时开始考试和结束考试。从而体现公平一致的原则。题库应包含所有的考试类型、题目内容和每题的分值,以便以后的随机抽题和为考生评分。并且数据库里也存储有每题对应的正确答案,考生的考试答案,这样可以方便评分。还对考生答案做了备份,方便以后的查阅和总结考试情况,以进一步更新考试,提高考试质量。还应把给每位考生随机生成的试题保存起来,方便查阅核对,并可由服务
5、器统一给对应考生发送试卷。最后把评卷的结果和考生成绩统计出来做备份,考生可在考试结束后直接查看考试结果。如果发现有疑问地方也可随时查看和核对。由此分析一共设计了七张表用来存储所有的考生信息和考试信息:考生信息表(包含属性:姓名、性别、准考证号、身份证号、所在学校)、考生考试信息表(包含属性:考生号、准考证号、考试时间、考试状态)、题库表(包含属性:题号、题目、题目类型、分值)、正确答案表(包含属性:题号、标准答案)、考生试卷表(包含属性:题号、考生号)、考生答案表(包含属性:题号、答案、考生号)和考生成绩表(包含属性:准考证号、成绩)。并为每个表设置了能唯一确定每位考生的属性。其中考生信息表里
6、设置属性(准考证号)为主关键字,并在考生考试信息表和考生成绩表里设置属性(准考证号)为考生信息表中属性(准考证号)的外部关键字。这样就可一一关联和对应每一位考生的信息。在考生考试信息表里为每位考生生成一属性(考生号)并设置其为此表的主关键字。以唯一确定每一位考生的考试时间和考试状态。在题库中设置属性(题号)为主关键字,这样就可以唯一确定每一题,防止题目的重复,也方便随机为考生抽题。并在考生试卷表、正确答案表和考生答案表里设置属性(题号)为外部关键字,这样就和题库中的题号一一对应起来,可减少这些表中的属性。从而实现整个数据库设计的完整性和一致性。在考生答案表和考生试卷表中同时设置属性(题号和考生
7、号)为外部关键字,这样就把考生和题目联系起来。通过关联唯一确定每位考生的试卷和答案,也方便了以后的分发试卷和为每位考生评卷。(1)考生信息和考生考试信息之间的联系:考试信息姓名性别准考证号身份证号所在学校考生信息考生号准考证号考试时间考试状态考生考试信息准考证号考生号11(2)题库和考生试卷之间的联系抽题题库题号考生号题号题目mn考生试卷题号题目题目类型分值(3)考生试卷和考生试卷之间的联系考生试卷答题题号考生号题号答案考生号题号题目答案11考生答案 (4)题库和正确答案之间的联系题库答案题号题目题目类型分值题号标准答案题号答案11正确答案(5)考生信息和考生成绩之间的联系考生信息成绩考生成绩
8、准考证号成绩11姓名性别准考证号身份证号所在学校考生信息考生考试信息考生考试信息查看成绩考生成绩查看题目考生试卷抽题11111m1题库mm答题n考生答案11对应答案正确答案在线考试系统模型整体E-R图4 逻辑设计整体逻辑数据库结构如下:数据库考生信息考生考试信息题库正确答案考生答案考生试卷 下面是将各个实体和联系转化为相应的二维表即关系模式,指定各个关系的主关键字和外部关键字,并对各个关系的约束加以限定:考生信息表字段名数据类型主关键字外部关键字参照的表取值说明姓名varchar(8)不允许为空性别char(2)只允许取“男”或“女”准考证号char(6)Yes数字字符身份证号char(18)
9、数字字符所在学校varchar(16)考生考试信息表字段名数据类型主关键字外部关键字参照的表取值说明考生号char(5)Yes准考证号char(6)Yes考生信息数字字符考试时间char(22)不允许为空考试状态varchar(6)不允许为空题库表字段名数据类型主关键字外部关键字参照的表取值说明题号intYes大于0题目varchar(100)不允许为空题目类型int 1或2或3分值int分值in(1,10)备注:其中题目类型中:1-判断题 2-填空题 3-选择题正确答案表字段名数据类型主关键字外部关键字参照的表取值说明题号intYes题库大于0标准答案varchar(20)Not null考
10、生试卷表字段名数据类型主关键字外部关键字参照的表取值说明题号intYes题库大于0考生号char(5)Yes考试考试信息Not null考生答案表字段名数据类型主关键字外部关键字参照的表取值说明题号intYes题库大于0答案Varchar(20)可为空考生号Char(5)Yes考生考试信息Not null考生成绩表字段名数据类型主关键字外部关键字参照的表取值说明准考证号Char(6)Yes考生信息数字字符成绩int成绩in(0,100) 缺省为05 物理设计建立数据库:CREATE DATABASE 在线考试系统ON ( NAME =在线考试系统, FILENAME = c:在线考试系统.md
11、f, SIZE = 10, MAXSIZE = 50, FILEGROWTH = 5 )LOG ON( NAME = library, FILENAME = c:在线考试系统.ldf, SIZE = 5MB, MAXSIZE = 25MB, FILEGROWTH = 5MB )数据库建表:考生信息表CREATE TABLE ksxx( sno int PRIMARY KEY IDENTITY,姓名 varchar(8) NOT NULL,性别 char(2),准考证号 varchar(6),身份证号 varchar(18),所在学校 varchar(16),)考生考试信息表CREATE TAB
12、LE ksksxx( sno int PRIMARY KEY IDENTITY,考生号 varchar(5) NOT NULL,准考证号 varchar(6),考试时间 varchar(22) NOT NULL,考试状态 varchar(6) NOT NULL,)题库表CREATE TABLE tk( sno int PRIMARY KEY IDENTITY,题号 int,题目 varchar(10),题目类型 int,分数 int,)正确答案表CREATE TABLE zqda( sno int PRIMARY KEY IDENTITY,题号 int,标准答案 varchar(20) NOT
13、 NULL,)考生试卷表CREATE TABLE kssj( sno int PRIMARY KEY IDENTITY,题号 int,考生号 varchar(5) NOT NULL,)考生答案表CREATE TABLE ksda( sno int PRIMARY KEY IDENTITY,题号 int,答案 varchar(20),考生号 char(5) NOT NULL,)考生成绩CREATE TABLE kscj( sno int PRIMARY KEY IDENTITY,准考证号 Char(6),成绩 int,)为了改善和优化数据库的性能和查询效果,为每个表创建了索引,具体代码如下: /
14、*考生信息表索引*/create unique index index_ksxx on ksxx(姓名,准考证号)/*考生考试信息表索引*/create unique index index_ksksxx on ksksxx(考生号)create unique index index_ksksxx1 on ksksxx(准考证号)/*题库表索引*/create unique index index_tk on tk(题号)/*正确答案表索引*/create unique index index_zqda on zqda(题号)/*考生答案表索引*/create unique index ind
15、ex_ksda on ksda(题号,考生号)/*考生试卷表索引*/create unique index index_kssj on kssj(考生号,题号)/*成绩表索引*/create unique index index_kscj on kscj(准考证号)为了实现表间数据的一致性和完整性,创建了触发器,具体代码如下:/*考生信息表触发器*/create trigger trigger_ksxx1on ksxxfor insert,update,deleteasif (SELECT LEN(准考证号) FROM inserted)6beginraiserror(准考证号长度不对!,10
16、,1)rollback transactionendelsebeginprint 添加成功!endif exists(select * from inserted where 身份证号 in(select 身份证号 from ksxx)begin print 身份证号已经存在!returnend/*考生考试信息表触发器*/create trigger trigger_ksksxxon ksksxxfor insert,update,deleteasif exists(select * from inserted where 准考证号 in(select 准考证号 from ksksxx)beg
17、inraiserror(准考证号重复!,16,1)rollback transactionendif not exists(select * from inserted where 考试时间 like %-%-%+ +%:%-%:%)beginraiserror(时间格式不对!,16,1)rollback transactionendif not exists(select * from inserted where 考试状态 in(待考,就绪,考试中,结束,缺考)beginraiserror(状态错误!,16,1)rollback transactionend/*题库表触发器*/create
18、 trigger trigger_tkon tkfor insert,update,deleteasif exists(select * from inserted where 题目 in(select 题目 from tk)beginraiserror(题目重复!,16,1)rollback transactionendif exists(select * from inserted where 题目 like %?and 题目类型=2)beginraiserror(题目类型错误!,16,1)rollback transactionend/*正确答案表触发器*/create trigger
19、trigger_zqdaon zqdafor insert,update,deleteasif exists(select * from inserted where 题号 in(select 题号 from zqda)beginraiserror(题号重复!,16,1)rollback transactionend/*考生答案触发器*/create trigger trigger_ksdaon ksdafor insert,update,deleteasif not exists(select * from inserted where 题号0 and 题号(select count(题号)
20、 from tk)beginraiserror(题号不在范围之内!,16,1)rollback transactionendif not exists(select * from inserted where 考生号 in(select 考生号 from ksksxx where 考试状态=考试中)beginraiserror(考生号有误!,16,1)rollback transactionend/*考生试卷触发器*/create trigger trigger_kssjon kssjfor insert,update,deleteasif exists(select * from inser
21、ted where 考生号 in(select 考生号 from kssj)beginraiserror(考生试卷已生成!,16,1)rollback transactionend/*考生成绩表触发器*/create trigger trigger_kscjon kscjfor insert,update,deleteasif exists(select * from inserted where 准考证号 in(select 准考证号 from ksksxx where 考试状态=结束)beginraiserror(准考证号错误!,16,1)rollback transactionend对在
22、线考试系统功能的描述,针对各功能,创建了不同的存储过程来实现,这样不但可以反复调用这些程序,大大减少了客户端的处理事务,同时也充分发挥服务器的功能,尽量减少网络上的堵塞。根据查询功能的需要,我创建了相应的视图,基于视图创建了相应的查询存储过程,这些存储过程还包括对各表内容信息的添加、删除和更新。并且在存储过程中也相应地加入了对数据完整性和一致性的约束条件。同时还创建了为指定考生或所有考生随机生成试卷和对指定考生或所有考生评卷功能的存储过程。(1)为所有考生随机生成试卷的存储过程的功能实现可简略为:我先创建了一个游标,用来暂时保存在线考试的考生的考生号,然后采用双重while循环,外层循环用来控
23、制游标,一条一条地读取考生号,内层循环用来为游标所定位的考生随机生成试题(我这里为了演示,只随机生成了5到题)。当游标结束时,也就为所有的考生生成了试卷。所谓随机就是用rand()函数在所有题号(例如1-100)之间随机生成一个随机数,由这个随机数唯一对应题库中的一道题目。具体代码如下:/*给单一考生生成试卷*/create proc pro_kssj_sj(ksh char(5)=null)asif not exists(select * from ksksxx where 考生号=ksh)beginprint 非法考生号!returnendif (select count(*) from
24、kssj where 考生号=ksh)5beginwhile (select count(*) from kssj where 考生号=ksh)5begininsert into kssj values(1+cast(rand()*10 as int),ksh)endreturnendelsebeginprint 题目已生成!endexec pro_kssj_sj S0001 /*执行示例*/*给所有考生生成试卷*/create proc pro_all_kssjasif not exists(select * from ksksxx)beginprint 暂无考试考生!returnendel
25、sebegindeclare cursor_all_kssj insensitive cursorfor select 考生号 from ksksxxfor read onlydeclare ksno char(5)open cursor_all_kssjfetch next from cursor_all_kssj into ksnowhile(fetch_status=0)beginwhile (select count(*) from kssj where 考生号=ksno)5begininsert into kssj values(1+cast(rand()*10 as int),ks
26、no) endfetch next from cursor_all_kssj into ksnoendclose cursor_all_kssj -关闭游标deallocate cursor_all_kssj -释放游标print 试卷已生成!endexec pro_all_kssj /*执行示例*/(2)为所有考生评卷功能的存储过程具体实现过程如下:创建一游标读取考生答案表里的所有信息,同样采用的是双重while循环来实现此功能。外层循环用来控制游标,并定义两个临时变量temp和sum,然后用内层循环来把考生答案和正确答案进行比较,如果结果一致,用变量temp从题库表中读取此题的分值,用变量
27、sum来累加分值,由于每位考生只有5道题,故内层循环只循环5次,最后变量sum中数值即位此考生的最后成绩,并通过存储过程pro_insert_cj(向考生成绩表中插入成绩)把考生成绩插入考生成绩表中。如此循环下去,直到游标结束,即位所有考生评卷过程结束。考生成绩表中也自动加入了每位在线考试的考生的分数。具体实现代码如下:/*给单一考生评分存储过程*/create proc pro_pf(ksno char(5)asdeclare cursor_pf insensitive cursorfor select 题号,答案 from ksda where 考生号=ksnofor read onlyi
28、f not exists(select * from ksksxx where 考生号=ksno and 考试状态=结束)beginraiserror(考生考试还未结束!,16,1)rollback transactionendelsebeginprint 考试已结束,继续!endif not exists(select * from kssj where 考生号=ksno)beginprint 没有此考生的答案!returnendelsebeginopen cursor_pfdeclare name sysname,result sysname,sum int,temp int,temp1
29、int,zkzh char(6)fetch next from cursor_pf into name,resultselect sum=0select temp=1select temp1=1while(temp1=5)beginif exists(select * from zqda where 题号=name and 标准答案=result)beginselect temp=(select 分值 from tk where 题号=name)select sum=sum+tempselect temp1=temp1+1-print haha-print sumfetch next from
30、 cursor_pf into name,resultendelsebeginselect temp1=temp1+1fetch next from cursor_pf into name,resultend-print temp1为:+cast(temp1 as char)-print name为:+cast(name as char)endclose cursor_pf -关闭游标deallocate cursor_pf -释放游标print sumselect zkzh=(select 准考证号 from ksksxx where 考生号=ksno)exec pro_insert_cj
31、zkzh,sum/*print 分数为:+cast(sum as char)*/endexec pro_pf S0005 /*执行示例*/*给所有考生评分存储过程*/create proc pro_all_pfasdeclare cursor_pf insensitive cursorfor select 题号,答案,考生号 from ksda order by 考生号for read onlybeginopen cursor_pfdeclare name sysname,result sysname,sum int,temp int,temp1 int,zkzh char(6),ksno c
32、har(5),ksno1 char(5)fetch next from cursor_pf into name,result,ksnowhile(fetch_status=0)beginselect sum=0select temp=1select temp1=1while(temp1=5)beginif not exists(select * from ksksxx where 考生号=ksno and 考试状态=结束)beginprint 考生考试还未结束!continueendelsebeginprint 考试已结束,继续!endif exists(select * from zqda
33、where 题号=name and 标准答案=result)beginselect temp=(select 分值 from tk where 题号=name)select sum=sum+tempselect temp1=temp1+1-print haha-print sumfetch next from cursor_pf into name,result,ksnoendelsebeginselect temp1=temp1+1fetch next from cursor_pf into name,result,ksnoendif temp1=5beginselect ksno1=ksn
34、oendend-print sumselect zkzh=(select 准考证号 from ksksxx where 考生号=ksno1)exec pro_insert_cj zkzh,sumendclose cursor_pf -关闭游标deallocate cursor_pf -释放游标/*print 分数为:+cast(sum as char)*/print -评分成功!endexec pro_all_pf /*执行示例*/6 实验数据示例:测试阶段通过在SQL Server 2000的查询分析器中输入相应的SQL语句,就可以得到相应的结果,具体如下所示:(1)查询考生信息表输入SQL
35、语句:SELECT (sno,姓名,性别,准考证号,身份证号,所在学校)FROM ksxx;(2)插入考生考试信息表输入SQL语句:INSERT INTO ksksxx (sno,考生号,准考证号,考试时间,考试状态)VALUES (01,05,12月31日,待考);(3)删除题库表输入SQL语句:DELETEFROM tkWHERE 题目类型 = A卷;(4)更新正确答案表(将题号为12的题目的答案改为B)输入SQL语句:UPDATE zqdaSET inanswer = BWHERE sno = 12;7 总结课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力
36、的重要环节,是对学生实际工作能力的具体训练和考察过程。通过这次课程设计增加很多认识,我先做了整体的分析,把要设计的表,表的属性,表间的关系全部弄清楚,并画了相应的关系图和E-R图,从而也就基本形成了这次设计的整体构架。在写代码的过程中明显感觉到很轻松,就是照着所设计的思路一步一步地进行。并得到以下总结:首先,流程是一切的根源,进度控制是项目顺利进行的基础。没有大局观,面对问题和变更就会不知所措了。其次,构架是很重要的,整体框架搭好,具体细节实现起来就是顺理成章的事了。最后,实践比一切空谈和理论更能学到东西。平时学的那些理论都不过是皮毛罢了,一旦不用很快就忘记,始终要在实践中才会发现问题才会努力
37、去解决才能成长。从理论到实践,在这些日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,毕竟是第一次做这样的设计,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,例如在设计整体架构设计各表之间的关系时,总
38、是考虑不够周到,数据的完整性和一致性把握不准。理论不够规范化,关系模式不够优越。为了实现这些,我也参阅了很多关于数据库设计方面的书,从中受益匪浅。特别是在实现为所有考生生成随机试题和给所有考生评卷的功能过程中,出现了很多难题,首先是怎么生成随机数的问题,另外还要考虑每位考生的试卷中不应该有一样的题目。并且控制好可为所有考生都产生试卷。评卷过程中的考生答案和正确答案的一一对照,怎么控制好游标来实现每循环一次正好为此考生评卷结束并且在考生成绩表中插入一条考生成绩的记录。这些内容都是通过参考资料才得以实现的。在这次课程设计过程中,也有很多没有想到的地方,通过和张老师的交流,完善了不少的功能。在此表示感谢。最后,在这次课程设计过程中,深刻感觉到自己知识的缺乏,还需要课外继续学习,不断完善和增加自身的知识和经验。8 参考文献1 王珊,萨师煊 数据库系统概论(第四版) 高等教育出版社 2006.2 孟凡容 关系数据库原理与设计 中国矿业大学出版社3 周峰 SQL Server2005中文版关系数据库基础与实践教程 电子工业出版社4 徐国智,汪孝宜 SQL Server数据库开发实例精粹 电子工业出版社专心-专注-专业