创建一个数据模型,该模型使用一大量 引用将不同类型的相关文档群组到一个集合中。单一集合模式对于仅使用一个数据副本进行多对多关系建模特别有用。在关注重复费用的用例中,此模式可以减少数据重复。
以下特征定义了单一集合模式:
将所有经常访问的文档一起存储在单个集合中。
将文档之间的关系存储为每个文档中的指针或结构体。
通过字段或大量上的索引映射文档之间的关系。该索引支持在单个查询中检索相关文档,而无需使用数据库连接操作。
在对具有高速操作、低延迟要求和频繁写入操作的系统进行建模时,请考虑使用单一集合模式。通过将文档分解为较小的部分(而不是大型嵌入式文档),数据库可以执行较小的写入操作并提高性能。
关于此任务
在以下示例中,应用程序允许学生查看他们在本学期注册的课程的状态。系统可能需要经常更新每个类的多个字段,例如 current_topic、upcoming_session_summary 或 next_class_time。为了避免参加同一班级的多个学生出现重复信息,我们希望将学生和班级作为单独的文档实体保留在同一集合中。
例子
请考虑以下班级和学生的示例模式。为了对它们的关系进行建模,班级和学生文档包含 links大量。该大量包括 doc_type 和 target 字段,用于引用学生实体和班级实体之间的关系。
类文档:
{ _id : "CS101-001", doc_type : "class", class_name : "Introduction to Programming", course_id : "CS101", instructor : { name : "Dr. Emily Smith", email : "emily.smith@example.com", office_hours : "Tuesdays and Thursdays 2:00 PM - 4:00 PM" }, semester : "Spring 2025", schedule : [ { day_time : "Monday 10:00 AM - 11:30 AM", location : "Room 101, Science Building" }, { day_time : "Wednesday 10:00 AM - 11:30 AM", location : "Room 101, Science Building" }, { day_time : "Friday 10:00 AM - 11:30 AM", location : "Room 101, Science Building" } ], current_topic : "Loops and Iterations", next_class_time : "2025-01-09T10:00:00Z", upcoming_session_summary : "We will explore different types of loops (for, while) and how to use them effectively in Python.", links : [ { target : "CS101-001", doc_type : "class" }, { target : "S10023", doc_type : "student" }, { target : "S12345", doc_type : "student" }, ... { target : "S12355", doc_type : "student" } ] }
学生文档:
{ _id : "S12345", doc_type : "student", name : "Jane Doe", major : "Computer Science", semester : "Spring 2025", registered_classes : [ { course_id : "CS101", class_instance_id : "CS101-001", class_name : "Introduction to Programming" }, { course_id : "MATH201", class_instance_id : "MATH201-002", class_name : "Calculus II" } ], links : [ { target : "CS101-001", doc_type : "class" }, { target : "MATH201-002", doc_type : "class" }, { target : "S12345", doc_type : "student" } ] }
要优化查询,请为 links字段索引:
db.students_classes.createIndex({ "links.target": 1, "links.doc_type": 1 })
您可以查询学生的信息及其参加的所有课程,而无需执行任何联接操作:
db.students_classes.find({ "links.target": "S12345" })
同样,您可以查询给定班级的所有注册学生:
db.students_classes.find({ "doc_type": "student", "links.target": "CS101-001" })