自定义 MongoDB 对象 _id 与复合索引

Custom MongoDB Object _id vs Compound index

所以我需要在MongoDB中创建一个查找集合来验证唯一性。要求是检查是否重复了相同的 2 个值。在 SQL 中,我会这样

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

如果上面的查询returns是一个计数那么说明这个组合不是唯一的。我有 2 个解决方案,但我不确定哪个更具可扩展性。我需要针对 30M+ 文档创建此映射。

解决方案1:

我在 key1 和 key2 上创建了一个包含复合索引的文档集合

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

解决方案2:

我编写应用程序逻辑以通过连接 value1 和 value2 来创建自定义 _id

{
  _id: <value1>_<value2>
}

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

提前致谢。

更新:

我的数据库已经有很多占用内存的索引,所以我想将索引大小保持尽可能小,特别是对于仅用于验证唯一性的集合。

我建议解决方案 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。只需使用键作为对象而不是下划线 _。如果以后需要,您也可以稍后添加更多密钥。

我认为解决方案 2 更符合您的要求table。生成MongoDB的_id值是绝对可以的。大多数应用程序确实使用 UUID 填充 _id 值。在您的情况下,假设此集合主要用于验证唯一性(即临时 table)或查找目的,将 _id 值的值 1 和 2 连接起来是有意义的。

解决方案 1 成本高,因为它需要额外的索引。同样,这取决于您是打算将此集合用于单独验证唯一性目的还是用于其他一些用例。

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