我无法理解在mongodb中存储数据的正确方法。尝试阅读了很多链接,但未能得出可靠的结论。我习惯了RDBMS风格。我手头有一个关系数据,db是Mongo。对于这个问题 - 比方说,我有一本可以拥有约200万册书籍的藏书。还有一种称为订阅的东西(例如:溢价,标准等)。总计200万的每本书肯定至少是任何一个订阅的一部分(也可能是多个订阅的一部分)。我可以在系统中最多订阅200个订阅。
这是关注的重点。如何在此处构建我的馆藏。我尝试了以下
方法1 。创建名为subscription_book_association的集合,其中一个文档对应于订阅,并将此订阅的所有书ID存储为文档中的json。在这里,我面临的问题是,如果订阅的书籍数量超过0.4百万,我必须将所有这些书籍的ID存储在同一文档中,最终我的文档限制超过16MB。
方法2 。创建一个名为book_subscription_association的集合,其中一个文档对应于一本书,并且我将所有订阅ID存储在文档中的每本书(作为数组)中。在这种情况下,我看到每当我对我的数据执行任何写操作时(例如,为订阅分配/取消分配一些新书),我基本上必须使用$ push / $ pull运算符更新订阅数组。这似乎花了太长时间(比如3-4分钟)。
例如:
{
"_id" : "Standard",
"description" : "Standard Subscription",
"status" : "Active",
}
{
"_id" : "",
"name" : "Java for beginners",
"code" : "TECH",
"vendor" : "XX Publications"
"Author" : "AAA"
"Year" : "2010"
}
{
"_id" : "",
"code" : "TECH",
"displayName" : "TECH/Java for beginners",
"name" : "Java for beginners",
"permission" : [
"Standard:R",
"Guest:R"
"Premium:RW"
],
"roles" : [
"Standard",
"Premium",
"Guest"
]
}
db.book_subscription_association.update( { }, { $pull: { roles: "Guest" } }, false,true)
db.book_subscription_association.update( { }, { $push: { roles: "Guest" } }, false,true)
方法3 。创建一个名为book_subscription_mapping的集合(类似于RDBMS中的映射表),其中我针对每个适用的订阅单独存储每本书的关联。在这种情况下,我在这个集合中拥有的文档数量非常庞大。最糟糕的情况是我在这个集合中有(200万个X 200)文档。这会占用大量存储空间,更新/读取查询也不是很有效。
答案 0 :(得分:0)
您采取的方法应该基于您期望更频繁的查询类型。
例如,如果您希望有更多查询询问订阅中的可用图书,您应该在订阅文档中包含一个列表,其中包含您希望向用户显示的详细信息(ID,标题等)。
另一方面,如果您希望有更多查询询问哪些订阅包含某本图书,那么您应该在该图书文档中包含订阅所需的所有详细信息。
实际上,在您的情况下,方法1或方法2之间的选择严格基于您对查询的期望。
关于您对方法1的存储ID的关注,您可以使用反向方法,以防订阅的图书集非常大(仅在该特定订阅中未包含的图书的ID中存储)。根据您期望的订阅范围,这可能实际上作为一般模式有效。
如果这种反向方法不起作用(每个订阅中仍有太多书籍),那么您最好的做法是遵循方法2并索引包含订阅列表的数组。您在帖子中显示的更新命令会影响整个集合(2 mil项目),因此它们需要更长的时间是很自然的。
有关如何对表进行非规范化的更多信息,MongoDB有一个nice series of blog posts on the topic。
答案 1 :(得分:0)
在对收集文档进行建模时,首先应该记住非规范化。您可以同时保留"预订数据&订阅数据"在单个集合中,始终建议将查询或查询序列的所有相关数据保留在同一磁盘位置(相同集合)中,以获得更好的性能。
请参阅以下链接以了解有效的模型设计。