我在互联网上看到了大量的例子,并在SO上回答了关于在两个实体之间建立多对多关系的各种方法。经常使用Users
和Roles
的示例。这个问题非常直接且易于理解,即使对于像我这样只有大约2个月使用MongoDb经验的人来说,有一半的时间用于对抗MongoDb中不需要的RDBMS模式模式。
然而,我有点失去了尝试建立一个三方多对多关系,这似乎在RDBMS世界中是直截了当的,但我无法思考如何在MongoDb中完成。
这是一个例子。
假设我有三个实体:Project
,User
,ProjectRole
。
每个User
可以有多个Projects
,每个Project
可以有多个Users
。
每个User
可以有多个ProjectRoles
,每个ProjectRole
可以有多个Users
。
另一个条件是ProjectRoles
只能与Users
分配到Project
。也就是说,如果Users
不属于ProjectRole
,则Project
不能拥有ProjectRoles
。
同样,Projects
仅通过Users
与join
相关。
因此,我有一些方法可以考虑创建这些关系,但很明显,这些(或许是全部)方式中的一些方式是RDBMS做事方式的直接结果。
1
为这三个实体创建一个{
"user_id" : ObjectId("someuserid"),
"project_id" : ObjectId("someprojectid"),
"projectrole_id" : ObjectId("someprojectroleid")
}
集合,使每个文档如下所示:
User
2
将Project
(嵌入)对象复制到{
"name" : "ProjectName",
"users" : [{ "username" : "FirstUserName", "projectRole" : "SomeRole" },
{ "username" : "SecondUserName", "projectRole": "SomeOtherRole"}]
}
文档,同时嵌入了ProjectRole对象/信息,它看起来像这样:
Project
第3
在User
文档中复制(嵌入)ProjectRole
对象,其User
1}中Project
的关联{
"name" : "UserName",
"projects" : [{ "projectname" : "SomeProject", "projectRole" : "SomeRole"},
{ "projectname" : "SomeOtherProject", "projectRole" : "SomeOtherRole"}]
}
>,这将是这样的:
Projects
选项1最有可能让我保持数据清洁并保持其完整性。但是阅读起来会很痛苦,因为它会超过3个集合(当项目变得更复杂时可能更多)。
至少对我来说,选项2和3似乎是最嵌入信息的MongoDb风格。我更喜欢2比3,因为Users
在层次结构中更高,后跟Project
。换句话说,从理论上讲,每个Users
比User
每个Projects
和User
分配的Project
要多得多。
选项2的问题是数据完整性。这可以通过确保每次更新(例如,服务器的User
)并搜索UserId
集合并更新此User
对象的所有实例(匹配于ID)。这可能是一个非常慢的操作(可能在Project
上编制索引会使其更快)但优先级是读取速度而不是快速更新。此外,假设{{1}}数据在一段时间内保持相当不变(另一方面{{1}}数据将经常更新。
过去这一点我不完全确定如何继续。我至少是在正确的轨道上,还是基于对MongoDb或甚至实际问题本身的一些基本误解的解决方案?