在我的应用程序中会有程序列表,每个程序将包含会话列表,每个会话将包含工作表列表。以更简单的方式,关系如下:
Programs --> Sessions --> Worksheets
在应用程序的某个时刻,我想以表格形式显示所选prgram的工作表列表:
--------------------------------
|Worksheet Name | Session Name |
--------------------------------
|Worksheet 1 | Session 2 |
|---------------|--------------|
|Worksheet 3 | Session 1 |
|---------------|--------------|
| | |
我的问题是我是否应该使用嵌入式文档,即在会话中嵌入prgram和worsheets中的会话,还是应该为程序,会话和工作表单独收集并使用类似于RDBMS中的外键的概念来关联它们?
我担心的是,如果我选择单独收集,那么对于上述情况,我将不得不执行太多查询以获得上述结果。
如果我去查询嵌套文档,那么查询子文档是非常有限的。
mongo中的文档限制为16MB,如果我使用嵌套文档,这就足够了。所以文档大小不是我关心的问题。
由于mongo基本上不是用于通货紧缩和规范化,所以我的问题是我是否应该使用关系来实现规范化模式,还是应该考虑上面的场景,使用嵌入式文档来获取规范化数据。
答案 0 :(得分:0)
在MongoDB中,数据建模的指导原则是设计文档,以便轻松快速地完成应用程序的最常见查询。这与RDBMS中的模式设计非常不同,后者侧重于规范化数据以使其不同部分之间的关系形式化,然后依靠连接以通过关系中的非规范化来获得正确的信息。 MongoDB并不适用于关系"这是不正确的。确实,它不处理规范化数据以及RDBMS,因为它不执行连接。联接必须在应用程序端完成。
Pontification完成后,一种简单的数据建模方法,可以让您的查询变得简单,就是将工作表存储为文档,将会话和程序数据非规范化到每个工作表中
{
"_id" : "p3s1ws0",
"session_id" : "s1",
"program_id" : "p3",
....
}
然后使用查询
检索给定program_idprog_id
的所有工作表
> db.worksheets.find({ "program_id" : prog_id })
最有可能添加一种排序来生成所需的表格形式。另一个现实的选择是让会话文档包含一系列工作表文档,假设每个会话的工作表数量可以限制在合理的数量,比如说200:
{
"_id" : "s0",
"program_id" : "p2",
"worksheets" : [
{
"_id" : "ws0",
...
},
...
],
...
}
查询保持不变
db.sessions.find({ "program_id" : prog_id" })
因为您可以从每个会话中获取会话的所有工作表。根据您希望如何制作表格形式,可能值得为查询使用聚合,但在问题中没有必要使用聚合。
两者之间的选择取决于它将如何影响您的其他查询和更新。例如,更新程序信息对于第一个模型来说更昂贵,因为它需要针对程序中的每个工作表进行更新,而不是更新程序中的每个会话,或者如果数据被建模则只更新一个文档。作为包含工作表数组的会话数组的程序文档(可能不想这样做)。
要了解有关此类数据建模的更多信息,我建议来自MongoDB博客的William Zola classic series。