在我看来,有两种方法可以在MongoDB中实现多对多关系,规范化或非规范化,两者都有权衡。如何确定要实施哪种模型?本OP的其余部分用例子解释了权衡。
将产品带到Sku关系。一种产品有许多skus,每个sku可能与许多产品相关联。 (我不打算将这个问题的答案特定于这个例子,而是任意多对多关系)。
归一化的
在标准化模型中,有两个集合,product和sku。两个集合中的每个Document都包含一个指向另一个集合的(对象)id数组。
优点:
缺点:
如,
db.store.sku.insert({
'sku_id': 1,
'name': 'cheese',
'price': 0.50,
'products': [10]
})
db.store.sku.insert({
'sku_id': 2,
'name': 'beef paddy',
'price': 0.25,
'products': [10]
})
db.store.product.insert({
'product_id': 10,
'name': 'cheese burger',
'skus': [1, 2]
});
db.store.product.insert({
'product_id': 11,
'name': 'hamburger',
'skus': [2]
});
规格化
在非规范化模型中,有一个集合。集合中的每个文档都包含一系列文档。
优点:
缺点:
,例如,
db.store.product.insert({
'product_id': 10,
'name': 'cheese burger',
'skus': [
{
'sku_id': 1,
'name': 'cheese',
'price': 0.50,
},
{
'sku_id': 2,
'name': 'beef paddy',
'price': 0.25,
}
]
});
db.store.product.insert({
'product_id': 11,
'name': 'hamburger',
'skus': [
{
'sku_id': 2,
'name': 'beef paddy',
'price': 0.25,
}
]
});
重要的是要注意,存在一些混合模型,其中最常查询的属性和/或最不可能被更改的属性存储在非规范化集合中,并且所有其他属性存储在参考集合中。
如何确定在MongoDB中实现多对多关系的方法?
答案 0 :(得分:0)
我认为您所谓的“非规范化”对于您的问题范围来说是完全错误的,因为您存储的是与数据结构无关的不同但等效的“sku”子文档。有两个不同的“sku_id”:2个字段就可以了,就像两个博客帖子都可以有不同用户的“第一”评论,但在你的场景中却没有。如果您在数据模型中允许破坏状态,那么即使在开始之前,您也会遇到严重问题。
您的“规范化”方法更好,但仍然不适合您的方案。您的数据建模意味着产品和SKU之间的关系(在图表方面)是有针对性的边缘,这意味着产品可以在没有SKU参考产品的情况下引用SKU。
我可以想到两种正确的建模方法:要么你只是引用产品中的SKU而只是没有引用,因为它隐含在那里。如果您需要从SKU到产品列表的方法,我建议构建一个查询,可能还有一个索引,但请不要双重链接。第二种方法是SQL n:m方法:拥有一组仅包含有关此关系的信息的文档。但说实话,我认为除非你在产品和SKU之间的这种联系上运行一些非常严肃的操作,否则这将是正确的。
哦,对于外键约束:MongoDB中没有这样的东西。甚至没有一个地方可以定义这样的东西,因为没有模式定义。