本系列文章翻譯自《50 Tips and Tricks for MongoDB Developers》,暫時沒有找到中文版,反正自己最近也在深入學習mongodb,是以正好拿來翻譯一下。一方面加強自己學習的效果,另一方面讓大 家也一起來體驗一下需要我們這些mongodb使用者需要注意的地方。
首先聲明自己的英文水準不是太高,加之有些英文翻譯成中文也找不到合适的詞來表達,是以在文章中可能會出現英文原詞,或者說有些地方的翻譯會有些生 硬,也就是說會出現直譯的地方。翻譯該書的主要目的是為大家學習探讨用的,如果有翻譯不精準的地方,或者說有更加精準的翻譯,還請大家指出,我會及時的更 正的,在此先謝過各位了。
Tip10.Design documents to be self-sufficient
将文檔設計成自給自足的
mongodb應該是一個大的,無聲的資料存儲容器。它本身不做任何處理,隻是負責存儲和讀取資料。你應該堅持這個目的,避免強迫mongodb進行一些用戶端可以進行的計算工作。甚至是一些例如計算平均數或者是計算加和這樣瑣碎的工作,都應該推給用戶端去做。
如果你非要進行一些需要計算的查詢,你有兩個選擇:
招來嚴重的性能懲罰。在mongodb中使用javascript進行計算。
在文檔中顯式的存儲這些資訊。
通常來說,你應該在文檔中顯式的存儲這些資訊。
假設你需要查詢apple和orange總共是30個的文檔。
{
"_id":123,
"apple":10,
"orange":12
}
如果文檔是上面的格式,就需要在查詢的同時使用javascript進行計算工作,非常低效。相反,在文檔中加一個total的字段。
"apple":12,
"orange":14,
"total":30
在更新apple和orange數量的時候,同時更新一下total的資訊。
>db.food.update({"_id":123},{"$inc":{"apple":10,"orange":-2,"total":8}})
>db.food.findOne()
"apple":22,
"orange":12,
"orange":38
假設是下面的情形,你的total存儲的是水果的類型數量。
"apple":10.
"orange":24,
"total":2
現在,你需要更新文檔,但是有可能增加字段,也有可能不增加字段。那你是否增加total的值呢?如果更新語句是下面的情況,你就需要更新total的值。
>db.food.update({"_id":123},{"$inc":{"banana":12,"total":1}})
相反的,如果banana字段已經存在了呢,我們就不應該增加total字段的值。但是在用戶端,我們不知道這些情況。
通常在這種情況下,我們有兩種處理方法:速度快,會産生不一緻;速度慢,沒有不一緻。
快速的辦法就是不管三七二十一,給total加1,同時讓應用意識到将來還需要檢查total的值是否正确。可以運作一個不間斷的批量處理任務,修正這些資料。
如果應用可以接受額外的處理時間,我們可以使用findAndModify方法,将文檔lock(設定一個locked字段,其他的寫請求會檢查這個字段),傳回文檔,然後在正确更新total的值之後,将lock字段設定為false。
>var resule=db.runCommand({"findAndModify":"food",
"query":{"_id":123,"locked":false},
"update":{"$set":{"locked":true}}})
>if ("banana" in result.value){
db.food.update({criteria,{"$set":{"locked":false}."$inc":{"banana":20}}})
}else{
db.food.update({criteria,{"$set":{"locked":false},"$inc":{"banana":3,"total":1}}})
本文轉自 virusswb 51CTO部落格,原文連結:http://blog.51cto.com/virusswb/798386,如需轉載請自行聯系原作者