MongoDB - 一个使用索引的集合

标签 mongodb collections indexing

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

例如:

假设我正在开发一个联系人管理器,我有两种类型的联系人“个人”和“企业”。我最初的想法是创建一个名为个人的集合和另一个名为企业的集合。但那是因为我习惯于在 sql 中开发,是的,这是合适的,因为每个表的列都不同。我越是开始考虑文档数据库的灵 active ,我就越开始思考,“我真的需要两个集合吗?”如果我只是在每个名为“联系人类型”的文档中添加一个字段并对其进行索引,我真的需要两个集合吗?由于每个文档中的字段/列不必全部相同(如在 sql 中),因此每个文档都可以有自己的字段,只要我有一个“文档类型”字段和该字段的索引。

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

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

我的问题是:这是 mongodb 开发人员使用的常用方法吗?为什么或者为什么不?如果有的话,有什么缺点?如果这是一种常用的方法,也请对使用这种方法给予肯定。谢谢你。

最佳答案

这是 Mongo 中的一个非常重要的观点,答案与其说是科学,不如说是一门艺术。拥有一个充满巨大文档的集合绝对是一种反模式,因为它不利于 Mongo 的许多功能。

例如,在检索文档时,您只能从集合中检索整个文档(不完全正确,但大部分如此)。因此,如果您有大量文档,则每次都会检索大量文档。此外,拥有大量文档会使分片的灵 active 降低,因为每个集合中只有顶级文档被索引(并因此被分片)。您可以将值索引到文档深处,但索引值与顶级文档相关联。

与此同时,纯关系模式也是一种反模式,因为您首先使用 Mongo 已经失去了很多参照完整性。此外,所有连接都在应用程序内存中完成,因此每个连接都需要一个完整的往返(慢)。

所以答案是在两者之间做一些事情。我想在这种情况下,您可能需要一个个人集合和一个不同的企业集合。我这样说是因为企业似乎有足够多的关联元数据,它可能会大量增加。 (此外,我个人与企业的关系似乎是多对多)。但是,个人可能有一个 Name 对象(具有 firstlast 属性)。将 Name 放入单独的集合中不是一个好主意。

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

编辑

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

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

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

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

关于MongoDB - 一个使用索引的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9557438/

相关文章:

c++ - MongoC++驱动程序BSON的构建:基于流与基于字符串解析。哪一个性能更好?

Java Spring Mongo 排序忽略大小写问题

java - HashMap内存效率

java - Spring @Transactional - 在持久/合并后使用集合

mysql - 当 WHERE 子句与该列进行比较时,不使用 TIMESTAMP 列上的索引

mongodb - MongoDB 和 Spark 中的连接过多

java - 如何在这个 ArrayList 中添加一个元素?

excel - 多条件vlookup优化(索引+匹配)

php - 这些 Mysql 外键是否也分配了索引

mongodb - 使用 $in 进行不区分大小写的搜索