You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何校验用户完成所有测试且不受试题增删操作影响

解决方案

核心思路是给用户每次测试参与行为独立建记录,快照存储参与当时的试题总量,和当次的答题数据绑定校验,完全隔离后续测试试题变动的影响。

表结构调整

  • 新增test_attempts(用户测试参与表),核心字段如下:
    CREATE TABLE test_attempts (
      id INT PRIMARY KEY AUTO_INCREMENT,
      user_id INT NOT NULL,
      test_id INT NOT NULL,
      initial_question_count INT NOT NULL COMMENT '用户参与本次测试时,该套测试的总题数快照',
      started_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '本次参与开始时间',
      completed_at DATETIME DEFAULT NULL COMMENT '本次参与完成时间,为NULL代表未完成',
      UNIQUE KEY uniq_user_test_ongoing (user_id, test_id, completed_at) COMMENT '每个用户每套测试同时仅存在一个未完成的参与记录'
    )
    
  • 原有user_answers表新增attempt_id字段,关联test_attempts表的主键,用来标识当前答题属于哪一次测试参与。

业务逻辑调整

  1. 用户首次进入某套测试(不管是第一次考还是重考)时,优先查询是否存在该用户对应测试、completed_at IS NULL的未完成参与记录:
    • 存在则直接复用该记录,读取initial_question_count作为本次需要完成的总题数
    • 不存在则新增一条参与记录,插入时实时查询当前questions表中对应test_id的试题总条数,写入initial_question_count字段
  2. 用户每提交一道试题答案,写入user_answers表后,统计当前attempt_id下已提交的去重question_id总条数
  3. 如果统计的已答题数等于本次参与的initial_question_count,直接将对应test_attempts记录的completed_at设为当前时间,标记本次测试参与完成

完成校验逻辑

  • 单套测试完成校验:判断对应用户、对应测试是否存在completed_at IS NOT NULL的test_attempts记录即可,和当前测试的试题数量完全无关
  • 重考资格校验:统计该用户所有测试的已完成参与记录数,和当前总测试套数对比,相等即可发起重考,重考时按上述逻辑生成新的test_attempts记录即可

轻量替代方案(不想新增表的场景)

如果不想新增test_attempts表,可以给questions表加created_at和is_deleted软删除字段,所有试题永远不做物理删除;同时user_answers表新增attempt_id字段标识每次考试批次,每个批次的第一道题提交时记录下当前该测试所有非删除的试题ID集合存在额外字段,后续校验只要判断该批次用户已答的试题ID是否完全覆盖记录的ID集合即可。

该方案冗余度更高,维护成本也更高,更推荐新增参与表的方案。

内容的提问来源于stack exchange,提问作者user_411

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 11:45:06