基本上有兩種建模數據結構的方法;您可以設計一個可以引用或嵌入比賽文檔的模式。
讓我們考慮下面的例子,它將游泳比賽和多種族關係進行映射。這證明了如果需要在另一個上下文中查看許多數據實體,則通過嵌入引用的優勢。在競爭和種族之間的數據這一個一對多的關係,競爭有多個種族實體:
// db.competition schema
{
"_id": 1,
"name": "Utmanaren",
"location": "town",
"startdate": "20150627",
"enddate": "20150627"
"races": [
{
"gender" : "m"
"style" : "freestyle"
"length" : "100"
},
{
"gender" : "f"
"style" : "butterfly"
"length" : "50"
}
]
}
隨着嵌入式數據模型,應用程序可以檢索只用一個查詢完整的游泳比賽資料。這種設計還有其他優點,其中之一就是數據局部性。由於MongoDB將數據連續存儲在磁盤上,因此將所需的所有數據放在一個文檔中可確保旋轉磁盤在磁盤上尋找特定位置所需的時間更少。嵌入式文檔的另一個優點是寫入數據時的原子性和隔離性。爲了說明這一點,說要刪除其具有價值的「蝴蝶」賽跑「風格」屬性的競爭,這可以通過一個單一的(原子)操作來完成:
db.competition.remove({"races.style": "butterfly"});
有關數據建模的詳細信息在MongoDB中,請閱讀文檔Data Modeling Introduction,特別是Model One-to-Many Relationships with Embedded Documents
另一個設計選擇是引用文檔遵循規範化模式,其中競賽文件包含對比賽的某一個文件:
// db.race schema
{
"_id": 1,
"competition_id": 1,
"gender": "m",
"style": "freestyle",
"length": "100"
},
{
"_id": 2,
"competition_id": 1,
"gender": "f",
"style": "butterfly",
"length": "50"
}
上述方法提高了執行查詢的靈活性。例如,檢索所有的孩子的比賽文件,其中主父實體competition
具有ID 1將是簡單,只需創建針對集合race
查詢:
db.race.find({"competiton_id": 1});
使用文檔的參考方法也以上規範化模式有優勢當你與非常不可預測的團隊之間有一對多的關係時。如果每個給定的competition
有幾百或幾千個race
文檔,嵌入選項就空間約束而言有很多挫折,因爲文檔越大,它使用的RAM越多,MongoDB文檔的硬核大小限制爲16MB。
如果您的應用程序經常使用競爭信息檢索競賽數據,那麼您的應用程序需要發出多個查詢來解析引用。
一般的經驗法則是,如果您的應用程序的查詢模式是衆所周知的,並且數據往往只能以一種方式訪問,那麼嵌入式方法就可以很好地工作。如果您的應用程序以多種方式查詢數據,或者無法預測數據查詢模式,則更適合這種情況的更規範化的文檔引用模型。
價:
MongoDB Applied Design Patterns: Practical Use Cases with the Leading NoSQL Database By Rick Copeland
您可以將比賽場作爲數組添加並將比賽記錄推送到比賽場。 –
Ahh okey,所以我會使用$ push並將新增的種族推到結構中? @İlkerKorkut – bark
是@bark,我在我的評論中發送了我想說的答案。 –