基于 MySQL + MongoDB 的在线考试系统数据库设计与实现

🌟 一、项目背景

随着在线教学的普及,传统纸笔考试逐渐被线上考试取代。为了记录学生考试数据、题目内容、成绩情况,一个稳定、清晰且易扩展的数据库至关重要。本项目仅负责数据库模块设计与实现,包括 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 示例可直接用于课程设计、小组作业或真实项目中。

相关推荐
Lgnazio42 分钟前
MYSQL数据库集群高可用和数据监控平台
数据库·mysql
摘星编程1 小时前
openGauss DataVec向量数据库集成:面向AI应用的相似性搜索与知识图谱存储
数据库·人工智能·知识图谱
r***18641 小时前
FlinkCDC实战:将 MySQL 数据同步至 ES
android·mysql·elasticsearch
p***62991 小时前
mysql-connector-java 和 mysql-connector-j的区别
android·java·mysql
27669582921 小时前
最新 _rand 分析
前端·javascript·数据库·node·rand·231滑块·_rand分析
一 乐1 小时前
宠物医院预约|宠物医院|基于SprinBoot+vue的宠物医院预约管理系统源码+数据库+文档)
java·前端·数据库·vue.js·后端·springboot
蟹至之1 小时前
【MySQL】视图
数据库·mysql·视图
Fuly10241 小时前
langchain基础教程(6)---构建知识库--①向量数据库-chromadb
数据库·langchain
凉凉的知识库1 小时前
在Go中读取MySQL Date类型,一不小心就踩坑
mysql·面试·go