MongoDB數據庫設計中6條重要的經驗法則,part 1

原文:6 Rules of Thumb for MongoDB Schema Design: Part 1

By William Zola, Lead Technical Support Engineer at MongoDB

“我有豐富的sql使用經驗,但是我是個MongoDB的初學者。我應該如何在MongoDB中針對一對多關係進行建模?”這是我被問及最多的問題之一。

我沒法簡單的給出答案,因爲這有很多方案去實現。接下來我會教導你如何針對一對多進行建模。

這個話題有很多內容需要討論,我會用三個部分進行說明。在第一部分,我會討論針對一對多關係建模的三種基礎方案。在第二部分我將會覆蓋更多高級內容,包括反範式化和雙向引用。在最後一部分,我將會回顧各種選擇,並給出做決定時需要考慮的因素。

很多初學者認爲在MongoDB中針對一對多建模唯一的方案就是在父文檔中內嵌一個數組子文檔,但是這是不準確的。因爲你可以在MongoDB內嵌一個文檔不代表你就必須這麼做。

當你設計一個MongoDB數據庫結構,你需要先問自己一個在使用關係型數據庫時不會考慮的問題:這個關係中集合的大小是什麼樣的規模?你需要意識到一對很少,一對許多,一對非常多,這些細微的區別。不同的情況下你的建模也將不同。

Basics: Modeling One-to-Few

一對很少

針對個人需要保存多個地址進行建模的場景下使用內嵌文檔是很合適,可以在person文檔中嵌入addresses數組文檔:


這種設計具有內嵌文檔設計中所有的優缺點。最主要的優點就是不需要單獨執行一條語句去獲取內嵌的內容。最主要的缺點是你無法把這些內嵌文檔當做單獨的實體去訪問。

例如,如果你是在對一個任務跟蹤系統進行建模,每個用戶將會被分配若干個任務。內嵌這些任務到用戶文檔在遇到“查詢昨天所有的任務”這樣的問題時將會非常困難。我會在下一篇文章針對這個用例提供一些適當的設計。

Basics: One-to-Many

一對許多

以產品零件訂貨系統爲例。每個商品有數百個可替換的零件,但是不會超過數千個。這個用例很適合使用間接引用---將零件的objectid作爲數組存放在商品文檔中(在這個例子中的ObjectID我使用更加易讀的2字節,現實世界中他們可能是由12個字節組成的)。

每個零件都將有他們自己的文檔對象



每個產品的文檔對象中parts數組中將會存放多個零件的ObjectID :



在獲取特定產品中所有零件,需要一個應用層級別的join

爲了能快速的執行查詢,必須確保products.catalog_number有索引。當然由於零件中parts._id一定是有索引的,所以這也會很高效。

這種引用的方式是對內嵌優缺點的補充。每個零件是個單獨的文檔,可以很容易的獨立去搜索和更新他們。需要一條單獨的語句去獲取零件的具體內容是使用這種建模方式需要考慮的一個問題(請仔細思考這個問題,在第二章反反範式化中,我們還會討論這個問題)

這種建模方式中的零件部分可以被多個產品使用,所以在多對多時不需要一張單獨的連接表。

Basics: One-to-Squillions

一對非常多

我們用一個收集各種機器日誌的例子來討論一對非常多的問題。由於每個mongodb的文檔有16M的大小限制,所以即使你是存儲ObjectID也是不夠的。我們可以使用很經典的處理方法“父級引用”---用一個文檔存儲主機,在每個日誌文檔中保存這個主機的ObjectID。



以下是個和第二中方案稍微不同的應用級別的join用來查找一臺主機最近5000條的日誌信息



所以,即使這種簡單的討論也有能察覺出mongobd的建模和關係模型建模的不同之處。你必須要注意一下兩個因素:

Will the entities on the “N” side of the One-to-N ever need to stand alone?

一對多中的多是否需要一個單獨的實體。

What is the cardinality of the relationship: is it one-to-few; one-to-many; or one-to-squillions?

這個關係中集合的規模是一對很少,很多,還是非常多。

Based on these factors, you can pick one of the three basic One-to-N schema designs:

基於以上因素來決定採取一下三種建模的方式

一對很少且不需要單獨訪問內嵌內容的情況下可以使用內嵌多的一方。

一對多且多的一端內容因爲各種理由需要單獨存在的情況下可以通過數組的方式引用多的一方的。

一對非常多的情況下,請將一的那端引用嵌入進多的一端對象中。

下一次我們將會看到如何使用雙向關係和反範式化去提升以上三種基本方案的性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章