寫給MongoDB開發人員的50條建議Tip1

來源:互聯網
上載者:User

本系列文章翻譯自《50 Tips and Tricks for MongoDB Developers》,暫時沒有找到中文版,反正自己最近也在深入學習mongodb,所以正好拿來翻譯一下。一方面加強自己學習的效果,另一方面讓大家也一起來體驗一下需要我們這些mongodb使用者需要注意的地方。

首先聲明自己的英文水平不是太高,加之有些英文翻譯成中文也找不到合適的詞來表達,所以在文章中可能會出現英文原詞,或者說有些地方的翻譯會有些生硬,也就是說會出現直譯的地方。翻譯該書的主要目的是為大家學習探討用的,如果有翻譯不精準的地方,或者說有更加精準的翻譯,還請大家指出,我會及時的更正的,在此先謝過各位了。

Tip#1.Duplicate data for speed,reference data for integrity

資料冗餘是為了效能,引用資料是為了完整性。

被多個文檔使用的資料,既可以直接嵌入文檔,也可以在文檔中引用資料。嵌入不一定就比引用好,反之,引用也不一定就比嵌入好。每一種都有自己的取捨,不論什麼,你都應該選擇適合你的應用程式的方式。

嵌入式的結構,可能會導致資料的不一致。假設你需要把圖1.1中的fruit的值從蘋果修改為鴨梨,你剛修改完food集合中的fruit值,這時候你的應用崩潰了,其他地方的fruit的值還是舊的值,這時候你的應用中就同時存在兩種不同的fruit值。

 

 

650) this.width=650;" border="0" src="http://www.bkjia.com/uploads/allimg/131228/134335JI-0.png" alt="" />

 圖1.1 嵌入式結構,fruit的值既存在於food集合,也存在於meals集合

 

不一致性也不是什麼大問題,但“不是大問題”也是有層級的,這個層級依賴於你的使用者需求。對於很多的應用,短時間內的不一致是可以接受的。假設一個使用者修改了他的姓名,在幾個小時內,他的舊文章繼續顯示他的舊姓名,是可以接受的。如果是即使短時間的不一致性也不能接受的話,你就需要考慮使用引用式的結構了。

650) this.width=650;" border="0" src="http://www.bkjia.com/uploads/allimg/131228/1343353C5-1.jpg" alt="" />

 圖1.2 引用式結構,fruit的值只存在於food集合,meals集合儲存fruit的id

 

 這需要權衡,你不能同時擁有最好的效能和確保及時的資料一致性。你必須決定哪一個對於你的應用來說更重要。

舉個例子來說。

假設我們正在設計一個購物車的應用,設計在mongodb中存在訂單資訊,訂單需要包含哪些資訊呢?

引用式結構

 
  1. a product: 
  2.   "_id":productId, 
  3.   "name":name, 
  4.   "price":price 
  5. a order: 
  6.   "_id":orderId, 
  7.   "user":userInfo, 
  8.   "items":[ 
  9.     productId1, 
  10.     productId2 
  11.   ] 



在訂單的item項中存在每一個productid,當需要顯示訂單內容的時候,首先查詢order集合,然後根據productid查詢product集合來擷取相應的產品名稱,沒有辦法做到只用一次查詢就可以擷取完整的訂單資訊。

如果產品資訊被更新,所有引用該產品的地方,都會顯示新的產品資訊。引用式的結構會拖慢讀資料的速度,但是在多個訂單會有很好的一致性,多個文檔能實現原子的變化只需要修改引用的文檔的資訊)。

嵌入式結構

 
  1. a product: 
  2.   "_id":productId, 
  3.   "name":name, 
  4.   "price":price 
  5. a order: 
  6.   "_id":orderId, 
  7.   "user":userInfo, 
  8.   "items":[ 
  9.     { 
  10.       "_id":productId1, 
  11.       "name":name, 
  12.       "price":price 
  13.     }, 
  14.     { 
  15.       "_id":productId2, 
  16.       "name":name, 
  17.       "price":price 
  18.     } 
  19.   ] 



將產品資訊嵌入到訂單資訊中,當需要顯示訂單的時候,只需要執行一次查詢即可。如果產品的資訊發生變化,而且我們想要將變化傳遞給訂單的話,我們需要更新多個獨立的訂單。

嵌入式結構加快了讀取的速度,但是一致性會降低,產品資訊不能被原子的在多個文檔中被修改。

決定使用嵌入式結構還是使用引用式結構,可以參考下面的因素:
 

  • 為很少發生變化的資料,每次都是再次讀取,你是否願意付出這樣的代價?

你是願意承擔1000次讀取帶來的懲罰?大多數應用,讀的壓力要大於寫的壓力。這需要你仔細測試自己的比例。

你正在考慮的引用資料的變化頻率如何?改變越少,越是贊成使用嵌入式的結構。引用很少改變的資料,例如名稱,出生日期,存貨標記和地址,是很不值的。

  • 一致性有多重要?

如果一致性很重要,你就應該使用引用式結構。例如,多個文檔需要原子的查看資料的變化。如果我們正在設計一個交易系統,有價證券只能在特定的時間才可以進行交易,到達不可以進行交易的時間,我們需要立即鎖定這些有價證券。這種事情在應用層級來操作可能更好,因為應用需要知道在什麼時間鎖定或者解鎖。

在上面的這個訂單應用中,一致性可能是有害的。假設我們想要給一個產品打折,20% off。我們不想更新已經存在的訂單中的產品資訊。這時候,我們需要的可能是一個快照,是下單時候的產品資訊。

  • 是否需要更快的讀取速度?

如果需要儘可能快的讀取速度,我們應該使用嵌入式結構。即時系統應該更多的使用嵌入式結構。

 

上面的這個訂單文檔是一個很好的嵌入式結構的例子,改變產品資訊的時候,我們不想改變訂單的資訊。在這裡,引用式結構不能帶給我們任何的好處。

在這個例子中,嵌入式結構是最佳的選擇。

最後給大家一個地址,Your Coffee Shop Doesn't Use Two-Phase Commit,,裡面的例子講述了在真實的環境中,如何處理一致性問題,以及相關的系統改如何設計。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.