2012-09-02 49 views
3

我想了解MongoDB文檔中數組和哈希的內部分配和放置(其中,我理解的是通過數組實現的)。MongoDB數據模式性能

在我們的域中,我們擁有的邏輯分組中的數千和數十萬個鍵 - 值對中的任何位置的文檔(認爲嵌套散列)。

我們代表的按鍵嵌套有一個點,例如,x.y.z,這在插入的MongoDB將自動成爲類似:

{ 
    "_id" : "whatever", 
    "x" : { 
     "y" : { 
      "z" : 5 
     } 
    } 
} 

最常見的操作是增加值,這是我們用做一個原子$inc,通常1000+值一次只有一個更新命令。新密鑰會隨着時間而增加,但不會頻繁,例如每天100次。

它發生在我的另一種表示將不會使用名字點,但一些其他的分隔符,創建平面文件,例如,

{ 
    "_id" : "whatever", 
    "x-y-z" : 5 
} 

鑑於鍵值對和使用的數量在$inc更新和新的密鑰插入模式而言,我在以下方面尋找的兩種方法之間的權衡指導:

  • 空間開銷上盤

  • 性能$inc更新

  • 的新密鑰插入

回答

2

MongoDB中的磁盤上存儲的文件是BSON格式的性能。還有就是BSON格式的詳細描述在這裏: - http://bsonspec.org/#/specification

雖然沒有使用短鍵名(因爲,你可以通過查看規格看到一些節省磁盤空間,將鍵值名稱嵌入到文檔中),在我看來,這兩種設計在使用磁盤空間方面幾乎沒有差別 - 使用分隔符( - )使用的額外字節可以通過不必擁有字符串單獨鍵值的終止符。

$ inc更新應該採用兩種格式幾乎相同的時間,因爲它們都將在內存中操作。與從磁盤讀取文檔所花費的時間相比,內存更新時間方面的任何改進都將是最小的舍入錯誤。

新鑰匙插入物的性能也應該幾乎相同。如果添加新的鍵/值對使新文檔足夠小以適應磁盤上的舊位置,則發生的所有事情就是更新內存中的版本並寫入日記條目。最終,內存版本將被寫入磁盤。

如果文檔超出之前爲其分配的空間,則新鍵插入會產生更多問題。在這種情況下,服務器必須將文檔移動到新位置並更新指向該文檔的所有索引。這通常是一個較慢的操作,應該避免。但是,您討論的模式更改不應該影響文檔移動的頻率。再次,我認爲這是一種洗滌。

我的建議是使用最適合開發人員生產力的模式。如果您遇到性能問題,那麼您可以單獨詢問有關如何擴展系統或提高性能的問題,或者兩者兼而有之。

+1

閱讀BSON規範,它看起來像數組和文檔不能有任何填充以供將來使用。你是否以同樣的方式閱讀?這似乎有點奇怪:在100K文檔中添加單個密鑰時,他們可能需要修改磁盤上的許多塊,因爲可能需要將多達100K的數據移動幾個字節。 – Sim

+0

你對規範是正確的。 MongoDB可以爲文檔分配額外的空間(填充因子),超過了規範允許的範圍:http://www.mongodb.org/display/DOCS/Padding+Factor另外,當您最初創建時,您可以使用手動填充因子該文檔:http://www.mongodb.org/display/DOCS/Padding+Factor#PaddingFactor-ManualPadding –

+0

在MongoDB中,當文檔超過其插槽時,只移動該文檔:文檔周圍的文檔保持不變。當一個文件被移動時,它被移動到一個足夠大的新記錄中,以保持它的新大小(加上任何填充因子)。額外的I/O來自重新索引,而不是移動其他文檔。 –