MongoDB-一个使用索引的集合



好吧,所以我在Mongodb中开发得越来越多,我开始怀疑是否需要多个集合,而不是有一个带索引的大集合(因为与表格数据不同,每个文档的列和字段可能不同)。如果我试图以最有效的方式进行开发(意味着更少的代码和可重复使用的代码),那么我可以对所有文档使用一个集合,只对一个字段进行索引吗。通过将所有文档都放在一个带有索引的集合中,我可以重用我所有的表单处理代码和其他代码,因为它们都将插入到同一个集合中。

例如:

比方说,我正在开发一个联系人管理器,我有两种类型的联系人"个人"one_answers"企业"。我最初的想法是创建一个名为"个人"的集合,并创建第二个称为"企业"的集合。但那是因为我习惯于在sql中开发,是的,这是合适的,因为每个表的列都不同。我越是开始考虑文档dbs的灵活性,就越开始想,"我真的需要两个集合吗?"?由于每个文档中的字段/列不必全部相同(就像sql中一样),所以只要我有一个"文档类型"字段和该字段的索引,每个文档都可以有自己的字段。

然后我接受了这个概念,开始思考,如果我只需要一个"个人"one_answers"企业"的集合,那么我甚至需要一个单独的"用户"或"联系历史"或任何其他数据的集合吗。理论上,我不能在一个集合中构建整个解决方案,并且在每个文档中都有一个字段来指定"类型"和索引,如"用户"、"个人联系人"、"业务联系人"、"联系人历史记录"等,如果它是与另一个文档相关的文档,我可以在"父关键字/外部"Id字段上进行索引。。。

这将允许我对前端进行动态编码,因为表单处理代码都是相同的(插入到同一集合中)。这将节省大量的编码,但我想通过使用索引和辅助索引来确保数据库仍能快速运行,并且不会随着集合的增长而在未来引发问题。可以想象,如果所有内容都在一个集合中,随着用户群的增长,这个集合中可能会有数十万甚至数百万个文档,但它会有索引和辅助索引来优化性能。

我的问题是:这是mongodb开发人员常用的方法吗?为什么?如果有的话,会有什么下降?如果这是一种常用的方法,请对使用这种方法给予肯定。非常感谢。

这是Mongo中的一个重要观点,答案更多的是一门艺术而非科学。拥有一个装满巨大文档的集合绝对是一种反模式,因为它与Mongo的许多功能背道而驰。

例如,在检索文档时,只能从集合中检索整个文档(虽然不完全正确,但大多数情况下)。所以,如果你有巨大的文档,你每次都会检索到巨大的文档。此外,拥有庞大的文档会降低分片的灵活性,因为在每个集合中只有顶级文档会被索引(因此也会被分片)。您可以对文档中的深层值进行索引,但索引值与顶级文档相关联。

同时,纯关系化也是一种反模式,因为一开始使用Mongo就失去了很多引用完整性。此外,所有连接都是在应用程序内存中完成的,因此每个连接都需要一个完整的往返(慢速)。

因此,答案是在两者之间做点什么。我想在这种情况下,你可能会想要一个针对个人的集合,而另一个针对企业的集合。我这么说是因为企业似乎有足够的元数据,可以大量增加。(此外,我个人与企业的关系似乎是多对多的)。但是,个人可能有一个Name对象(具有firstlast属性)。如果将Name作为一个单独的集合,那将是一个坏主意。

10gen关于架构设计的一些信息:http://www.mongodb.org/display/DOCS/Schema+设计

编辑

此外,Mongo对事务的支持有限——以原子聚合的形式。当您将一个对象插入mongo时,整个对象要么已插入,要么未插入。所以您的应用程序域需要某些对象之间的一致性,您可能希望将它们保留在同一文档/集合中。

例如,考虑一个要求User始终具有Name对象(包含FirstNameLastNameMiddleInitial)的应用程序。如果以某种方式插入了User而没有相应的Name,则数据将被认为是损坏的。在RDBMS中,您将围绕插入UserName的操作包装事务。在Mongo中,我们确保NameUser在同一个文档(聚合)中,以实现相同的效果。

你的例子不太清楚,因为我不了解商业案例。脑海中浮现的一件事是Mongo对继承有极好的支持。将所有用户、个人和潜在的企业放在同一个集合中可能是有意义的(取决于应用程序的建模方式)。如果一个人有很多联系人,你可能希望每个人都有一系列的ID。如果你的应用程序要求你快速预览联系人,你可以考虑复制个人的一部分并存储一组联系人对象。

如果你习惯了RDBMS的思维,你可能会认为所有的数据都必须是一致的。事实是,这可能并不完全正确。最近,DDD社区大力宣扬将原子聚集体应用于该领域的概念。当您像业务用户一样深入查看您的域时,一致性边界应该变得明显。

MongoDB和NoSQL通常是关于去规范化数据和减少连接的。这违背了SQL的正常思维。

在您的情况下,我看不出您有任何理由想要单独的集合,因为这会引入不必要的复杂性和性能开销。例如,如果您想要一个按字母顺序显示所有联系人的屏幕,请考虑。如果你有一个单独的联系人集合,那么这真的很容易,但如果你有两个集合,那就变得更复杂了。

如果您的应用程序有多个存储联系人的用户,我会有多个集合。然后,我会为每个用户提供一个集合。这使得提取用户联系人变得非常容易。

最新更新