在我看來,有兩種方法可以在MongoDB中實現多對多關係,規範化或非規範化,兩者都有折衷。我如何決定實施哪種模式?本OP的其餘部分用示例解釋了權衡。MongoDB:多對多 - 什麼時候執行非規範化vs規範化?
產品與Sku的關係。一個產品有許多skus,每個sku可能與許多產品相關聯。 (我不打算這個問題的答案是特定於這個例子,而是任意的多對多關係)。
歸
在一個標準化的模型中,有兩個集合,產品和SKU。兩個集合中的每個Document均包含一個指向其他集合的(對象)ID數組。
優點:
- 數據不重複
- 防止更新/插入/缺失的異常
- 查找的SKU的不同列表(除了外鍵陣列)並不昂貴
缺點:
- M兩個單獨文檔的差異不是原子的
- 查找給定產品的skus或相反,需要對數據庫進行兩次查詢。
- 外鍵並不強制,但貸款是自我異常(但僅限於外鍵陣列)
例如,
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]
});
規格化
在非規範化的模式,有一個集合。集合中的每個文檔都包含一組文檔。
優點:
- 修改到單個文檔是原子
- 查找的SKU對於給定的產品,或者相反,僅需要一個查詢到的分貝。
缺點:
- 數據被複制
- 適合於更新/插入/缺失距平
- 找到單品的獨特名單是昂貴的(我假設是db.store.product .distinct(skus)相對較貴)
eg,
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中實現多對多關係的方法?