🌟 一、项目背景
随着在线教学的普及,传统纸笔考试逐渐被线上考试取代。为了记录学生考试数据、题目内容、成绩情况,一个稳定、清晰且易扩展的数据库至关重要。本项目仅负责数据库模块设计与实现,包括 MySQL 的结构化考试数据管理与 MongoDB 的非结构化日志数据处理。
🧱 二、系统数据库需求概述
本项目数据库主要支持以下场景:
-
管理用户(学生、老师、管理员)
-
存储考试信息
-
记录考试过程与成绩
-
保存题目内容与对应答案
-
记录用户行为日志(采用 MongoDB)
📐 三、数据库 E-R 模型(文本解释版)
以下结构用于指导小组成员绘制 ER 图:
1. User 用户表
-
用户 ID
-
用户名
-
密码
-
姓名
-
邮箱
-
电话
-
状态
2. Exam 考试表
-
考试 ID
-
考试标题
-
时长
-
开始 / 结束时间
-
状态
3. Question 题目表
-
题目 ID
-
所属考试
-
题目内容
-
标准答案
-
分值
4. Exam_Record 考试记录表
-
记录 ID
-
考试 ID
-
学生 ID
-
开始时间
-
结束时间
-
提交状态
🛠 四、MySQL 数据库实现
1)创建 User 用户表
CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID', username VARCHAR(50) UNIQUE NOT NULL COMMENT '用户名', password VARCHAR(100) NOT NULL COMMENT '密码(加密后)', real_name VARCHAR(50) COMMENT '真实姓名', email VARCHAR(100) COMMENT '邮箱', phone VARCHAR(20) COMMENT '手机号', status TINYINT DEFAULT 1 COMMENT '状态:1正常 0禁用', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' );
2)外连接查询示例
需求:查询所有学生及其考试记录(即使未参加考试也显示)
左外连接:
SELECT u.username, u.real_name, er.exam_id, er.status FROM exam_myda.exam_record er RIGHT JOIN user_myda.user u ON u.id = er.user_id;
右外连接(反向):
SELECT u.username, u.real_name, er.exam_id, er.status FROM user_myda.user u LEFT JOIN exam_myda.exam_record er ON u.id = er.user_id;
3)批量插入数据
INSERT INTO user (username, password, real_name, email, phone) VALUES ('student01', '123456', '张三', 'stu01@example.com', '13800000001'), ('teacher01', '123456', '李老师', 'tea01@example.com', '13800000002'), ('admin01', '123456', '管理员', 'admin01@example.com', '13800000003');
4)修改数据(基于上面插入的数据)
简单更新示例:
UPDATE user SET phone = '13900000001' WHERE username = 'student01';
批量修改示例:
UPDATE user SET status = 0 WHERE email LIKE '%example.com';
🍃 五、MongoDB 基础操作(用于日志系统)
以下内容简洁直接,可写进报告:
连接数据库:
use exam_system
插入数据:
db.log.insertOne({ user: "student01", action: "login", time: new Date() })
批量插入:
db.log.insertMany([{ user: "student01", action: "view_exam", time: new Date() }, { user: "student01", action: "submit_exam", time: new Date() }])
查询数据:
db.log.find()
修改数据:
db.log.updateOne({ action: "login" }, { $set: { action: "login_success" } })
删除数据:
db.log.deleteOne({ action: "submit_exam" })
MongoDB 用于记录日志十分合适,因为它存储结构灵活、无需固定字段。
🔧 六、关键技术点总结
关键技术 1:数据库分库设计
系统将数据分为两个数据库:
-
user_myda:用户相关
-
exam_myda :考试相关
这样可以减少表数量过多导致的性能下降,提高扩展性。
关键技术 2:外键与外连接
考试记录 exam_record 与 user / exam 表通过外键关联,这确保了数据一致性。
同时外连接解决了查询"未参与考试也显示"的业务痛点。
关键技术 3:MongoDB 用于日志系统
日志写入频繁、结构多变,使用 MongoDB 代替 MySQL 能显著提高插入性能与灵活性。
❗ 七、开发过程中的难点 & 解决方案
难点 1:跨数据库 JOIN 报错
例如:
1146 - Table 'user_myda.exam_record' doesn't exist
原因: exam_record 位于 exam_myda,而你在 user_myda 执行 JOIN。
解决: 查询时必须带上库名,例如:
SELECT ... FROM exam_myda.exam_record JOIN user_myda.user ON ...
难点 2:外键找不到对应表
1824 - Failed to open the referenced table 'question'
原因: question 表不在当前数据库。
解决:
外键引用不能跨数据库,必须放在同一库或不设外键。
难点 3:规范化与性能冲突
题目内容大、图片多,若全部放 MySQL 会导致查询性能下降。
解决:
-
题目主体放 MySQL
-
题目富文本或图片可放 OSS / MongoDB / JSON 字段
提升查询效率。
🎉 八、总结
本项目通过 MySQL 处理结构化数据、MongoDB 处理日志,实现了一个高扩展、清晰结构、性能良好的考试系统数据库方案。文章提供的 SQL 和 MongoDB 示例可直接用于课程设计、小组作业或真实项目中。