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

多技术领域选择题存储:MongoDB vs RDBMS及MongoDB存储检索方法

选择题数据存储:MongoDB vs RDBMS方案对比及MongoDB实践

一、哪种方案更优?

你的核心需求是按特定技术/能力维度检索题目,数据量从数百到数千级,两种方案都能支撑,但差异主要在灵活性和维护成本:

RDBMS(如MySQL、PostgreSQL)

  • 优势:数据结构规整,适合属性固定、要求严格数据一致性的场景。如果你的题目属性(题干、选项、答案、技能标签)不会频繁变更,用RDBMS能保证数据严谨性,关联查询(比如统计某技能下的题目数量)效率稳定。
  • 劣势:后续要给题目加新属性(比如难度分级、出题年份)时,必须修改表结构,流程繁琐。技能标签多对多关联需要建中间表,查询时要做JOIN,虽然数据量不大时影响有限,但灵活性远不如MongoDB。

MongoDB

  • 优势:文档型存储天然适配半结构化数据,每道题可直接作为一个独立文档存储,技能标签用数组字段嵌入即可,无需额外中间表。后续加新属性直接在文档里补充,不用改整体结构,灵活性拉满。按技能标签检索的语法简洁,数千级数据量完全无压力。
  • 劣势:如果需要复杂的跨维度聚合统计(比如跨多个技能的答题数据交叉分析),MongoDB的聚合查询学习成本比SQL高一点,但你的需求里这类场景应该不多。

结论:如果题目属性可能灵活调整,或者更看重按技能检索的便捷性,选MongoDB更合适;如果数据结构完全固定,且依赖强一致性和复杂SQL查询,RDBMS更稳妥。从你的需求(按技能展示题目、数据量增长到数千)来看,MongoDB的灵活性更匹配。

二、MongoDB的存储与检索实现

1. 数据结构设计

将每道题作为独立文档,核心字段参考如下:

{
  "_id": ObjectId("60d21b4667d0d8992e610c85"), // MongoDB自动生成的主键
  "question_title": "以下哪个不是Python的内置数据类型?", // 题干
  "options": [
    {"label": "A", "content": "list"},
    {"label": "B", "content": "tuple"},
    {"label": "C", "content": "map"},
    {"label": "D", "content": "dict"}
  ], // 选项列表
  "correct_answer": "C", // 正确答案
  "skills": ["Python基础", "数据类型"], // 关联的技能/能力维度,用数组存储
  "difficulty": "简单", // 可选:后续可扩展的属性
  "user_choices": [ // 可选:存储用户答题记录,也可拆分到独立集合
    {"user_id": "user123", "choice": "C", "submit_time": ISODate("2024-05-20T10:00:00Z")},
    {"user_id": "user456", "choice": "D", "submit_time": ISODate("2024-05-20T10:15:00Z")}
  ]
}
  • 关键设计:用skills数组存储关联技能标签,这是实现按技能检索的核心。
  • 优化建议:如果用户答题记录较多,建议把user_choices拆成独立集合(比如命名为user_question_answers),结构为{"user_id": "...", "question_id": "...", "choice": "...", "submit_time": "..."},避免单文档过大,也方便单独查询用户答题记录。

2. 检索操作

(1)查询某技能下的所有题目

比如查找关联"Python基础"的题目:

// MongoDB Shell命令
db.questions.find({
  "skills": "Python基础"
})

如果要同时匹配多个技能(如既属于Python基础又属于数据类型):

db.questions.find({
  "skills": {$all: ["Python基础", "数据类型"]}
})

(2)统计某技能下的题目数量

db.questions.countDocuments({
  "skills": "Python基础"
})

(3)查询某用户在某技能下的答题记录

若用户答题记录存在独立集合,可先查技能对应的题目ID,再关联用户记录:

const questionIds = db.questions.find({skills: "Python基础"}, {_id: 1}).map(doc => doc._id);
db.user_question_answers.find({
  user_id: "user123",
  question_id: {$in: questionIds}
})

也可用聚合管道直接关联查询:

db.user_question_answers.aggregate([
  {$match: {user_id: "user123"}},
  {$lookup: {
      from: "questions",
      localField: "question_id",
      foreignField: "_id",
      as: "question_info"
    }},
  {$match: {"question_info.skills": "Python基础"}},
  {$project: {user_id: 1, choice: 1, submit_time: 1, question_title: "$question_info.question_title"}}
])

3. 性能优化

  • 给skills字段建索引,加快检索速度:db.questions.createIndex({skills: 1})
  • 若用户答题记录较多,给user_id和question_id建复合索引:db.user_question_answers.createIndex({user_id: 1, question_id: 1})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:05:11