# 考试与试卷数据模型问题分析报告 ## 一、问题概述 当前系统中,**考试(Exam)** 和 **试卷(Paper)** 被设计为**同一个数据对象**,导致两个本应独立的概念混在一起,造成功能边界模糊和数据冗余。 --- ## 二、当前数据模型分析 ### 2.1 现有数据库表结构 ``` et_exam_examination -- 考试信息表(独立) ├── id -- 考试ID ├── planid -- 关联培训计划ID ├── name -- 考试名称 ├── starttime/endtime -- 考试时间窗口 ├── duration -- 考试时长 ├── isonline -- 是否在线 └── shouldJoin/realJoin -- 应考/实考人数 et_exam_exampaper -- 试卷表(有examid字段关联考试) ├── id -- 试卷ID ├── examid -- 关联考试ID(外键) ├── name -- 试卷名称 ├── totalpoints -- 总分 ├── passpoint -- 及格分数 ├── description -- 描述 ├── category -- 所属知识点 ├── state -- 状态(是否可编辑) └── sum1~sum4 -- 各题型数量统计 et_exam_question -- 试题题库表 ├── id ├── type -- 题型(1单选2多选3判断4问答) ├── subject -- 题目内容 ├── answer -- 正确答案 └── optionA~F -- 选项 et_exam_exampaper_question -- 试卷-题目关联表 ├── id ├── examid -- 考试ID ├── questionid -- 试题ID ├── score -- 分值 ├── isMust -- 是否必答 └── num -- 题目序号 ``` ### 2.2 实际使用的数据源 代码中实际使用的是 **`et_exam_exampaper_and_editexampaper`** 视图/联合表,将考试和试卷合并: ```sql -- 在 SQL 映射中大量使用 select * from et_exam_exampaper_and_editexampaper ``` 这个视图/表包含了考试和试卷的所有字段,导致两个概念完全混在一起。 --- ## 三、核心问题分析 ### 3.1 问题一:考试与试卷概念混淆 | 维度 | 考试(Exam) | 试卷(Paper) | |------|-----------|-------------| | **本质** | 一次考试活动 | 一份试题集合 | | **属性** | 时间、人数、时长 | 题目、总分、及格分 | | **生命周期** | 有开始/结束时间 | 可长期存在、复用 | | **关联** | 关联培训计划 | 可关联多个考试 | **当前问题**:考试和试卷共用同一张表,无法体现"同一份试卷可用于多次考试"的业务场景。 ### 3.2 问题二:字段冗余与混用 在 `exampaper_edit.ftl` 中,同一个表单同时包含: ```html 开放时间:startdate / enddate 考试时长:sc (小时) 试卷名称:name 试卷描述:description 及格分数:passpoints 试卷类别:category ``` 这导致: - 一份试卷不能同时用于多场考试(因为考试时间不同) - 修改考试时间会影响试卷本身 ### 3.3 问题三:题型统计字段冗余 `et_exam_exampaper` 表中有 `sum1~sum4` 字段存储各题型数量: ```sql `sum1` int -- 单选题数量 `sum2` int -- 多选题数量 `sum3` int -- 判断题数量 `sum4` int -- 问答题数量 ``` **问题**:这些统计值应该通过 SQL 动态计算,而不是冗余存储。试题数量变化时需要手动同步更新。 ### 3.4 问题四:关联表使用不一致 从 `et_exam_limitation.map.xml` 中可以看到: ```sql -- limitation 表使用 exam_id 关联 select * from et_exam_limitation where exam_id = ? -- usertest 表也使用 exam_id 关联 select * from et_exam_usertest where exam_id = ? ``` 这里的 `exam_id` 实际存储的是**试卷ID**(因为 `et_exam_exampaper_and_editexampaper` 视图本身就是考试+试卷的合并),命名语义混乱。 ### 3.5 问题五:考试和问卷共用一套表 从代码中可以看到,`pg` 参数区分: | pg值 | 类型 | 说明 | |------|------|------| | 1 | 考试/试卷 | 需要评分 | | 2 | 调研问卷 | 不评分 | 但底层共用同一套表结构,只是业务逻辑不同。这种设计虽然灵活,但缺乏清晰的边界。 --- ## 四、业务场景冲突示例 ### 场景1:同一试卷用于多次考试 **业务需求**:某课程结业考试,3月份和6月份各举办一次,但使用同一份试卷。 **当前限制**: ``` 方案A:创建两份试卷(内容完全相同,但ID不同)→ 数据冗余 方案B:使用同一试卷修改时间 → 影响历史考试记录 ``` **理想设计**: ``` 试卷表(不变) ← 考试表(每次考试独立) ``` ### 场景2:考试延期 **当前问题**: - 用户需要修改考试时间,但操作入口在"编辑试卷" - 修改后影响所有关联记录 **理想设计**: - 考试时间在考试表中独立管理 - 试卷表只负责试题内容 --- ## 五、建议的数据模型重构 ### 5.1 分离考试和试卷表 ``` ┌─────────────────────────────────────────────────────────────┐ │ 当前设计(混用) │ ├─────────────────────────────────────────────────────────────┤ │ et_exam_exampaper_and_editexampaper │ │ ├── 考试属性(时间、人数) │ │ └── 试卷属性(题目、总分) │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ 建议设计(分离) │ ├─────────────────────────────────────────────────────────────┤ │ et_exam_exampaper(试卷表) │ │ ├── id, name, description, category │ │ ├── totalpoints, passpoint │ │ └── creatperson, edittime │ ├─────────────────────────────────────────────────────────────┤ │ et_exam_examination(考试表) │ │ ├── id, paper_id(关联试卷) │ │ ├── name, starttime, endtime, duration │ │ ├── shouldJoin, realJoin │ │ └── state, leader │ ├─────────────────────────────────────────────────────────────┤ │ et_exam_exampaper_question(关联表) │ │ ├── id, paper_id, question_id │ │ ├── score(每场考试可单独设置分值) │ │ └── num, isMust │ └─────────────────────────────────────────────────────────────┘ ``` ### 5.2 关键改进点 | 改进项 | 当前 | 建议 | |--------|------|------| | 试卷复用 | 同一试卷不能用于多场考试 | 一份试卷可关联多场考试 | | 时间独立 | 考试时间绑定试卷 | 考试时间独立管理 | | 题目分值 | 固定分值 | 每场考试可单独设置 | | 题型统计 | 冗余字段 sum1~sum4 | 动态 SQL 计算 | --- ## 六、重构风险评估 | 风险项 | 等级 | 说明 | |--------|------|------| | 历史数据迁移 | 高 | 现有数据需要重新整理 | | 业务逻辑修改 | 高 | 涉及多个控制器和页面 | | 关联表改动 | 中 | limitation、usertest 等表需同步修改 | | 测试工作量 | 高 | 需要全面回归测试 | --- ## 七、建议执行步骤 1. **分析阶段**:梳理所有使用 `et_exam_exampaper_and_editexampaper` 的代码 2. **设计阶段**:完成新的数据模型设计 3. **开发阶段**: - 新建考试表相关逻辑 - 保留试卷表 - 修改关联表 4. **数据迁移**:编写迁移脚本 5. **测试验证**:全面回归测试 6. **上线部署**:灰度发布 --- ## 八、附录:涉及文件清单 ### SQL 映射文件 - `et_exam_exampaper_and_editexampaper.map.xml` - `et_exam_editexampaper.map.xml` - `et_exam_usertest.map.xml` - `et_exam_limitation.map.xml` ### 前端模板 - `exam/exampaper.ftl` - `exam/exampaper_edit.ftl` - `exam/exampaper_list.ftl` - `exam/exampaper_detail.ftl` - `exam/exam.ftl` - `exam/exam_list.ftl` ### Java 控制器 - `ExamController.class` - `ExampaperController.class` - `ExamResultController.class` - `ExampaperServiceImpl.class` - `ExamServiceImpl.class` --- *报告生成时间:2026-04-16*