2012-09-13 37 views
20

在我看來,當你創建一個蒙戈文件,並有現場{key, value}它有時不會有一個值,你有兩個選擇:存儲空VS不存儲密鑰MongoDB中所有

  1. {key, null}即在該領域
  2. 寫null值,不要在文件中的密鑰存儲在所有

兩個選項是可查詢容易在一個您查詢{key : null}另您查詢{key : {$exists : false}}

我不能真正想到在應用場景中會產生任何影響的兩個選項之間的任何差異(除了選項2的存儲略少)。

任何人都可以告訴我,如果有任何理由,寧願兩種方法之一,而爲什麼?

編輯

要求也發生,我認爲指數可能表現不同的兩種情況,即稀疏索引可以選擇2創建,但我仍然試圖比較和了解的問題後這兩種方法中的全部索引考慮是什麼。

+2

對於什麼是值得的,「稍微小一點的存儲」在巨大的規模上可能更重要,特別是當你談論內存中工作集的大小時。 – Christopher

回答

24

事實上你也有第三種可能性: key: ""(空值)

你忘了一個關於空值的特異性。 對 的查詢key: null將檢索所有關鍵字爲空的文檔其中不存在關鍵字。

當對$exists:false的查詢將只檢索doc字段鍵不存在時。

要回到您的確切問題,它取決於您的查詢和數據代表。 如果您需要通過示例來保持該值,則用戶設置一個值然後取消設置值,則應將該字段保留爲空或空。如果你不需要,你可以刪除這個字段。

+3

我會遠離密鑰:「」,因爲這意味着它是一個字符串。如果你檢索這樣一個字段,並且你做了一些像isKeyExists(key)這樣的事情,即使它是一個空字符串,它也會傳遞爲true。所以我們假設你正在期待一個布爾錯誤的空間。 –

15

請注意,由於MongoDB不使用字段名稱字典壓縮,因此field:null消耗磁盤空間和RAM,而根本不存儲密鑰不會消耗資源。

7

它真的可以歸結爲:

  • 您的方案
  • 你的查詢方式
  • 你的索引需要
  • 你的語言

我個人選擇了存儲空鍵。它使我的應用程序更容易集成。我在Active Record中使用PHP,並且使用空值可以讓我的生活變得更加輕鬆,因爲我不需要將應用程序中的字段應用程序放在壓力之下。此外,我不需要製作任何複雜的代碼來處理魔法來設置不存在的變量。

我個人不會因爲如果存儲像""空值你不小心,你可以有兩個空值null"",然後你就會有專門查詢的HAP-危險時間。所以我個人更喜歡null空值。

至於空間和索引:它取決於有多少行可能沒有這個列,但我懷疑你會真正注意到由於一些額外的文檔與null in的索引大小增加。我的意思是存儲的差異是mineute特別是如果相應的密鑰名稱很小的話。這也適用於大型設置。

我很坦率地說不清楚$existsnull之間的索引使用的不過null可以通過查詢所有腦幹因爲記住,MongoDB是無模式的,這意味着你沒有要求必須在doc那場更標準化的方法它再次產生兩個空值:不存在和null。所以選擇一個或另一個更好。我們選擇null

+0

謝謝......但我不相信使用null會使應用程序代碼更簡單(至少不會在我使用的C#驅動程序中)。沒有複雜的代碼,因爲在C#驅動程序中不存在的鍵會自動反序列化爲空。 –

+0

@ZaidMasud在C#中以及驅動程序問題中,您都擁有強類型語言。這就是爲什麼這是一個很難回答的問題,因爲在所有平臺上都沒有標準,與CSS或HTML或OOP等不同,它完全取決於你。 – Sammaye

2

另一點你可能要考慮的是當你使用像Hibernate OGM這樣的OGM工具時。

如果您使用Java,Hibernate OGM支持JPA標準。因此,如果您可以編寫JPQL查詢,那麼如果要切換到OGM工具支持的備用NoSQL數據存儲,理論上會很容易。

JPA沒有在Mongo中爲$ exists定義等價物。所以如果你的集合中有可選的屬性,那麼你不能爲相同的JPQL寫一個適當的JPQL。在這種情況下,如果屬性的值存儲爲NULL,那麼仍​​然可以編寫如下所示的有效JPQL查詢。

SELECT p FROM pppoe p where p.logout IS null;