在在线考试系统的开发中,试卷和题目相关的表设计是核心基础,需要兼顾数据存储的规范性、查询的高效性以及后续功能扩展的便利性。合理的表结构能够避免数据冗余,同时支撑试卷生成、题目管理、成绩统计等核心业务场景。

核心业务需求分析
设计表结构前需要先明确核心业务场景,考试系统通常包含以下需求:
- 支持创建多套试卷,每套试卷包含多个题目
- 题目支持多种类型,比如单选题、多选题、判断题、简答题等
- 每个题目可以有多个选项,选项需要标记是否正确
- 试卷可以设置总分、考试时长、适用人群等属性
- 支持题目复用,同一道题目可以出现在多套不同的试卷中
表结构设计思路
根据需求分析,我们需要设计三张核心表,分别是试卷表、题目表、试卷题目关联表,同时题目选项可以单独设计一张选项表,具体设计如下:
1. 试卷表 exam_paper
用于存储试卷的基础信息,每个试卷对应一条记录。
CREATE TABLE `exam_paper` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '试卷ID', `paper_name` VARCHAR(100) NOT NULL COMMENT '试卷名称', `total_score` INT NOT NULL DEFAULT 100 COMMENT '试卷总分', `exam_duration` INT NOT NULL COMMENT '考试时长,单位分钟', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态 1启用 0停用', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='试卷基础信息表';
2. 题目表 exam_question
用于存储所有题目的公共信息,支持题目在不同试卷中复用。
CREATE TABLE `exam_question` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '题目ID', `question_type` TINYINT NOT NULL COMMENT '题目类型 1单选 2多选 3判断 4简答', `question_content` TEXT NOT NULL COMMENT '题目内容', `score` INT NOT NULL DEFAULT 5 COMMENT '题目默认分值', `difficulty` TINYINT NOT NULL DEFAULT 1 COMMENT '难度 1简单 2中等 3困难', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='题目基础信息表';
3. 试卷题目关联表 exam_paper_question
用于记录试卷和题目的关联关系,同时可以存储该题目在当前试卷中的实际分值,实现题目分值的灵活配置。
CREATE TABLE `exam_paper_question` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '关联ID', `paper_id` INT UNSIGNED NOT NULL COMMENT '试卷ID', `question_id` INT UNSIGNED NOT NULL COMMENT '题目ID', `actual_score` INT NOT NULL COMMENT '该题目在当前试卷中的实际分值', `sort` INT NOT NULL DEFAULT 0 COMMENT '题目在试卷中的排序', PRIMARY KEY (`id`), UNIQUE KEY `uk_paper_question` (`paper_id`,`question_id`), KEY `idx_paper_id` (`paper_id`), KEY `idx_question_id` (`question_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='试卷题目关联表';
4. 题目选项表 exam_question_option
用于存储题目的所有选项信息,单选题和多选题有多条选项记录,判断题可以有对、错两个选项,简答题可以没有选项记录。
CREATE TABLE `exam_question_option` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '选项ID', `question_id` INT UNSIGNED NOT NULL COMMENT '题目ID', `option_content` VARCHAR(500) NOT NULL COMMENT '选项内容', `is_correct` TINYINT NOT NULL DEFAULT 0 COMMENT '是否为正确选项 1是 0否', `sort` INT NOT NULL DEFAULT 0 COMMENT '选项排序', PRIMARY KEY (`id`), KEY `idx_question_id` (`question_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='题目选项表';
常见业务查询示例
查询某套试卷的所有题目及选项
需要关联四张表,获取试卷下的题目列表以及每个题目的所有选项。
SELECT ep.paper_name, eq.id AS question_id, eq.question_type, eq.question_content, epq.actual_score, eqo.option_content, eqo.is_correct FROM exam_paper ep JOIN exam_paper_question epq ON ep.id = epq.paper_id JOIN exam_question eq ON epq.question_id = eq.id LEFT JOIN exam_question_option eqo ON eq.id = eqo.question_id WHERE ep.id = 1 ORDER BY epq.sort, eqo.sort;
统计某套试卷的总分
通过关联表计算试卷所有题目的实际分值总和,验证是否与试卷设置的总分一致。
SELECT ep.paper_name, SUM(epq.actual_score) AS total_actual_score, ep.total_score AS paper_set_score FROM exam_paper ep JOIN exam_paper_question epq ON ep.id = epq.paper_id WHERE ep.id = 1 GROUP BY ep.id, ep.paper_name, ep.total_score;
设计注意事项
在实际落地时,还需要注意以下几点:
- 可以给常用查询字段添加合适的索引,比如
exam_paper_question表的paper_id和question_id字段,提升查询效率 - 如果题目内容需要支持富文本,可以将
question_content字段类型调整为MEDIUMTEXT - 如果需要记录题目的使用次数、正确率等统计信息,可以在
exam_question表中添加对应的统计字段,定期更新 - 试卷和题目的状态字段建议用枚举值或者字典表维护,方便后续扩展更多状态类型
mysqlexam_paperexam_questiondatabase_designtable_structure修改时间:2026-07-10 21:18:13