2012-09-13 38 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;