我想与您讨论一下,在 MongoDB 中建模 N:M 关系时,使用双向嵌入而不是单向嵌入是否有意义。
假设我们有两个实体: AProduct可以属于许多(少数)类别, and a Category可以有很多(很多)Products.
两种方式嵌入
如果我们使用这种方法,我们的类别看起来像这样:
{
_id: 1,
name: "Baby",
products: [2]
}
{
_id: 2,
name: "Electronics",
products: [1, 2]
}
And products:
{
_id: 1,
name: "HDMI Cable",
categories: [2]
}
{
_id: 2,
name: "Babyphone",
categories: [1, 2]
}
Queries:
如果我们想获取属于特定类别的产品:
const category = categoriesCollection.findOne({name: "Electronics"});
const products = productsCollection.find({_id: {$in: category.products}}).toArray();
如果我们想获取属于特定产品的类别:
const product = productsCollection.findOne({name: "Babyphone"});
const categories = categoriesCollection.find({_id: {$in: product.categories}}).toArray();
单向嵌入
因为一个产品可能只属于两个或三个类别,但一个类别可以有数百万个产品,所以我会将类别嵌入到产品中,而不是相反。因此我们可以确信我们永远不会达到 16 MB 的最大文档大小。
我们的产品看起来与上面相同,但类别将不再有“产品”字段。
如果我们想获取特定产品的类别,我们的查询与上面相同:
const product = productsCollection.findOne({name: "Babyphone"});
const categories = categoriesCollection.find({_id: {$in: product.categories}}).toArray();
相反,如果我们获取特定类别的产品,我们的查询将更改为:
const category = categoriesCollection.findOne({name: "Electronics"});
const products = productsCollection.find({categories: category._id}).toArray();
在我们的产品系列中,我们放置了(多键)index在类别数组上,所以性能应该没问题。
我的结论
对我来说,单向嵌入似乎是更好的解决方案,因为我们不会达到最大文档大小,同时相对于双向嵌入方法没有任何(?)缺点。为什么有人想要进行双向嵌入?我错过了什么吗?从性能上来说,应该是差不多的,或者不是?
你怎么认为?