转载地址:http://blog.csdn.net/koastal/article/details/54233566
系统说明
- 共100道不定项选择题,存储在MySQL数据表(ques)中
- 每个考生的题目顺序不一样
- 150人同时答题和交卷
系统设计
时间同步
要求考生在同一时间进行交卷,就要统一时间。
因此我们以服务器时间为准,在考生登录时获取服务器时间作为开始时间。
打乱题目顺序
使用mysql中的by rand()
方式打乱题目顺序,其中rand种子是考生的考号。
可以保证每个考生的题目顺序是不同的,但是又能保证自己题目的顺序是一定的。
Redis缓存答题记录
为提高系统的响应速度,将考生作答结果保存到Redis数据库中。
Redis存储已作答题目
将考生所有的已作答题目存储到Redis集合中,用于在系统中显示考生答题记录。
sadd ansLog:201101 1
sadd ansLog:201101 2
- 1
- 2
Redis存储答题结果
将考生的答题结果存储到Redis哈希中
hmset ans:201101 1 AD # 记录数据库中题目id为1的答题结果
hmset and:201101 2 ED # 记录数据库中题目id为2答题结果
hmset ans:201101 1 DE # 更新数据库中题目id为1答题结果
hget ans:201101 2 # 查看数据库中题目id为2答题结果
- 1
- 2
- 3
- 4
Redis存储考生成绩
使用键值对存储考生成绩即可
set grades:201101 98
set grades:201102 78
set grades:201103 83
- 1
- 2
- 3
成绩的计算
当考生提交或修改答案时(假设修改了id为8的题目),通过PHP语言在服务器上执行如下操作:
- 更新Redis中的哈希
ans:201101
中key为8时,对应的value - 从mysql中取出题目的正确答案,用于计算分数
- 判断
ansLog:201101
是否包含该题目id,如果包含则为修改,如果不包含则为首次提交 - 对于首次提交,答案正确增加分数,答案错误分数不变
- 对于修改操作,答案从正确修改为错误,则减分;答案从错误修改为正确,则加分
Redis对考生成绩排序
首先,将所有的考号存储到List中用于排序
lpush users 201101 201102 201103
sort users by grades:* desc #获得按照成绩降序排列的序号
sort users by grades:* get grades:* desc #获得按照成绩降序排列的成绩
- 1
- 2
- 3
提交试卷
150人同时提交试卷,也就意味着同时对mysql有大量的写入操作发生(从Redis将数据写入到MySQL)。
我们可以通过让提交操作,sleep(rand(0,5))
通过一定的随机等待时间之后再进行操作。
提交试卷时,需要通过PHP语言,将Redis中的以下数据同步到数据库中:
- 答题结果
需要将该考生的答题结果ans:201101
存储到mysql数据库中,便于日后查看。 - 考生成绩
从ans:201101
中取出考生每道题的答案,然后和正确答案对比,更加严谨的计算得到考生的分数,然后再将最后的分数写入到mysql中。
说明
考生的题目的顺序是和考生的考号关联的(select * from ques order by rand('201101')
),因此无需将该顺序存储到mysql中。
考生的作答记录,可以通过mysql中的答题记录分析得到,因此也无需存储。
通过前面的说明,计算考生的分数有两种方式:
1. 简单快速的方案 通过判断当前提交的答案正确与否,是否为修改操作,在原来分数的基础上增加、较小分数。
2. 严谨复杂的方法 对考生作答的每一道题目的结果都进行判断,得到最终的分数。
考生成绩的排序方式也有两种:
1. 通过Redis的sort,对Redis中的考生成绩进行排序
2. 通过MySQL的order by,对MySQL数据库中的考生成绩进行排序
Redis中简单快速的计算分数和排序的方式用于考试过程中,实时显示考试成绩,因为该操作较频繁,需要较快的响应速度。