2016-08-09 24 views
1

所以我需要在MongoDB中创建一个查找集合来验证唯一性。要求是检查是否重复相同的2个值。在SQL,我想这样的事情自定义MongoDB对象_id vs化合物索引

SELECT count(id) WHERE key1 = 'value1' AND key2 = 'value2' 

如果上面的查询返回的计数那么就意味着该组合不是唯一的。我有两个解决方案,但我不确定哪一个更具可扩展性。有30M +文档需要我创建这个映射。

解决方法1:

我创建KEY1和KEY2与化合物索引文档的集合

{ 
    _id: <MongoID>, 
    key1: <value1>, 
    key2: <value2> 
} 

溶液2:

我写应用程序逻辑以通过串联创建自定义_id value1和value2

{ 
    _id: <value1>_<value2> 
} 

个人而言,我觉得第二个更优化,因为它只有一个索引,doc的大小也更小。但我不确定创建我自己的_id索引是否是一种好的做法,因为它们可能不是完全随机的。你怎么看?

在此先感谢。

更新:

我的数据库已经拥有了很多,所以我想保持索引大小,以尽可能低专为它们仅用于验证的独特收藏,其占用内存索引。

+0

你的意思是SQL计数大于1,这个值不是唯一的吗?在解决方案2中,重复的值不会被加载到MongoDB中,这会很好吗? – notionquest

+0

不,我的意思是SQL计数大于0.如果它的1意味着条目已经存在,所以我不应该添加重复。对于解决方案2,如果mongo不允许我添加重复项,那是正确的。 – umair

回答

2

我建议解决方案1点即使用复合索引,并使用两种不同的性质和KEY1 KEY2

db.yourCollection.ensureIndex({ "key1": 1, "key2": 1 }, { unique: true }) 
  1. 如果需要,可以通过单独的领域很容易地搜索。即如果您只需要通过key1或key2进行搜索,那么使用复合索引将很容易。如果您使用组合键制作_id,则很难按个别字段进行搜索。
  2. 在设计文档时,Mongo中文档的大小是最不受打扰的。
  3. 如果在不久的将来,如果您需要更改相同文档的相对于其他值的键值,这将非常简单。请记住,如果您在其他收藏文档中使用了此文档的引用。
  4. 就您的可伸缩性而言,_id索引是连续的,易于裁剪,您可以让MongoDB管理它。
  5. 如果您使用这些键进行搜索,那么它将使用该索引,否则它将使用其他所需的索引进行搜索。

如果你仍然不是搜索那么你就可以解决方案1去思考大小的文件,使_id像

{_id:{key1:<value1>,key2:<value2>}} 

通过这个,你可以搜索特定的_id.key1了。

更新:

是如果文件大小是您的关心比维护。如果您确定密钥将来不会修改相同文档的将来,并且如果它仍在修改并且没有其他集合中的引用,那么您可以使用解决方案1.只需使用键作为对象而不是下划线_。如果将来可以添加更多的密钥,以后也可以。

+0

感谢您的解决方案!你不觉得复合索引会占用更多的内存,再加上不需要额外的_id索引。在我的情况下,我不会查询一个单一的键,因为集合只是为了确保value1 + value2不被重复。 – umair

+0

问题是我的数据库已经有很多索引占用内存,所以我想保持我的索引大小尽可能低。 – umair

+0

@umair:我已经更新了答案。让我知道如果你有更多的关注 –

1

我认为解决方案2更适合您的要求。生成MongoDB的_id值完全可以。大多数应用程序不会使用UUID填充_id值。在你的情况下,假设这个集合主要用于验证唯一性(即临时表的种类)或查找目的,为_id值连接值1和2是有意义的。

解决方案1 ​​是昂贵的,因为它需要额外的索引。同样,这取决于您是要使用此集合来验证唯一性目的,还是针对其他用例。

请注意,您需要创建唯一的复合索引,以便它不允许插入重复值的数据。