我有两个集合,lists
和items
,每个项都可以属于任意数量的列表,并且每个列表都有一个自定义位置。为了避免过度架构,哪一个性能更好?为什么?
答:维护列表数组及其在每个项目文档中的位置,如下所示:
/* item schema */
{
_id: ObjectID, // itemID
lists: [
{
_id: ObjectID, // the listID
orderNr: Number, // the position in that specific list
}
]
}
B:维护一个额外的集合contexts
,该集合将按照itemID在任何给定列表中出现的顺序存储itemID数组:
/* context schema */
{
_id: ObjectID,
listID: ObjectID,
items: [
{
_id: ObjectID, // itemID
orderNr: Number // position of item in the list
}
]
}
我个人的理解是B是更好的选择,因为您可以通过_id
字段查询列表的上下文文档,从items数组的开头获取一些ID,然后通过它们的_id
字段直接查询这些项。
而在版本A中,如果我想象有5,000个项,每个项存在于3-4个不同的列表中,并且每个项都改变了位置,那么Mongo要根据每个项中的数组中的值找到所有这些项似乎要做很多工作(我知道Mongo需要搜索和比较所有项目,而不是只按_id
查询有限数量的项目,能够在找到last _id项的时刻停止)。
但也许MongoDB的内部工作方式中有一些我不知道的东西并没有让选项A成为问题?这肯定意味着维护工作量大大减少。或者也许还有第三种方法我没有看到?
1条答案
按热度按时间wgeznvg71#
我认为,选项A对于模式上下文是更好的选择。
但这两个都需要使用查询
aggregation
,即使会有额外的集合。问题是,我们需要提高性能,以下是一些生产步骤,
$lookup
时,使用ObjectId
之类的索引来联接集合,ref:https://www.mongodb.com/docs/manual/core/aggregation-pipeline-optimization/#std-label-aggregation-pipeline-optimization-indexes-and-filters$lookup
操作的输出,在内部使用pipeline
有很多工具可以生成分页数据,我建议使用使用mongodb本地驱动器的工具
这里是一个生成分页示例工具,它只需要一次查询就可以生成分页数据,且能够执行多次连接(查找)
mongodb-pagination