避免无界数组
Overview
MongoDB 丰富的模式模型的优势之一是能够将数组存储为文档字段值。 通过将数组存储为字段值, 就可以在单个文档中建立一对多或多对多的关系模型, 而不是像在关系数据库中那样跨单独的集合建模。
但是,如果您不断向文档中的数组添加元素,则应小心谨慎。如果不限制数组中元素的数量,您的文档可能会增长到不可预测的大小。随着数组不断增长,对该数组读取和构建索引的性能逐渐下降。不断增长的大型数组会给应用程序资源造成压力,并使您的文档面临超过 BSON 文档大小限制的风险。
相反,请考虑为数组设限以提高性能,并将文档大小保持在可管理范围内。
例子
考虑以下 publishers
集合的模式:
// publishers collection { "_id": "orielly" "name": "O'Reilly Media", "founded": 1980, "location": "CA", "books": [ { "_id": 123456789, "title": "MongoDB: The Definitive Guide", "author": [ "Kristina Chodorow", "Mike Dirolf" ], "published_date": ISODate("2010-09-24"), "pages": 216, "language": "English" }, { "_id": 234567890, "title": "50 Tips and Tricks for MongoDB Developer", "author": "Kristina Chodorow", "published_date": ISODate("2011-05-06"), "pages": 68, "language": "English" } ] }
在此情况下,books
数组无界限。该出版公司每发行一本新书,便会向 books
数组添加一个新的子文档。随着出版公司不断发行图书,这些文档最终会变得很大,并对应用程序造成不成比例的内存压力。
为避免出现可变的无界数组,可将 publishers
集合分为两个集合,一个是 publishers
集合,另一个是 books
集合。与其在 publishers
文档中嵌入整个 book
文档,不如在图书文档中引用出版商:
// publishers collection { "_id": "oreilly" "name": "O'Reilly Media", "founded": 1980, "location": "CA" }
// books collection { "_id": 123456789, "title": "MongoDB: The Definitive Guide", "author": [ "Kristina Chodorow", "Mike Dirolf" ], "published_date": ISODate("2010-09-24"), "pages": 216, "language": "English", "publisher_id": "oreilly" } { "_id": 234567890, "title": "50 Tips and Tricks for MongoDB Developer", "author": "Kristina Chodorow", "published_date": ISODate("2011-05-06"), "pages": 68, "language": "English", "publisher_id": "oreilly" }
更新后的此模式会删除 publishers
集合中的无界限数组,并使用 publisher_id
字段在每个图书文档中放置对该出版商的引用。此操作可确保每个文档均有可管理的大小,且不存在文档字段变得过大的风险。
文档引用可能需要 $lookups
如果应用程序分别加载图书和出版商信息,则此方法尤其有效。如果应用程序需要同时使用书籍和信息,则需要执行 $lookup
操作来联结来自 publishers
和 books
集合的数据。$lookup
操作的性能不是很高,但在这种情况下,为了避免使用无界数组,还是值得一试。
了解详情
要了解有关 MongoDB 数据建模和灵活的模式模型的更多信息,请参阅数据建模简介。
如需了解如何利用文档引用建立关系模型,请参阅使用文档引用建立一对多关系模型
要了解如何在 MongoDB 中查询数组,请参阅查询数组。
MongoDB 还提供免费的 MongoDB University 数据建模课程:MongoDB 数据建模。
MongoDB.live 2020 演讲
要了解如何将灵活数据模型整合到您的架构中,请参阅 MongoDB.live 2020 中的以下演示文稿:
通过 MongoDB 数据建模了解 MongoDB 中的实体关系及其实现示例。
通过高级模式设计模式了解您可以整合到模式的高级数据建模设计模式。