将 MongoDB 中的 _id 类型更改为整数是不是不好?

Posted

技术标签:

【中文标题】将 MongoDB 中的 _id 类型更改为整数是不是不好?【英文标题】:Is it bad to change _id type in MongoDB to integer?将 MongoDB 中的 _id 类型更改为整数是否不好? 【发布时间】:2012-12-12 19:49:26 【问题描述】:

MongoDB 使用 ObjectId 类型作为 _id。

如果我将_id设为递增整数会很糟糕吗?

(如果您有兴趣,请使用this gem)

【问题讨论】:

这真的取决于。有一个参数表示否,因为它是唯一的 id(自动递增),但有一个参数表示是,因为保持 id 唯一性(必须查询另一个计数器集合)所需的维护开销。这就像在插入之前必须检查所有 _id 的唯一性一样,最终会妨碍插入速度并造成长时间锁定。 嗯,为了这个简单的功能,DB 中有这么多操作? =( 是的,很多,因为当然 MongoDB 没有服务器端自动递增 id 的感觉,你可以在这里查看它需要什么:docs.mongodb.org/manual/tutorial/… 事实上这是原因之一为什么MongoDB服务器端不支持这种类型的id 实际上,mongo 使用ObjectID 数据类型,因为它是_id 的。 ObjectID 是 12 字节的二进制数据,而不是字符串。请参阅MongoDB Documentation 了解更多信息。 【参考方案1】:

你可以这样做,但你有责任确保整数是唯一的。

MongoDB 不像大多数 SQL 数据库那样支持自动递增字段。当您的分布式或多线程应用程序具有多个创建新数据库条目的进程和/或线程时,您必须确保它们使用相同的计数器。否则,可能会发生两个线程尝试在数据库中存储具有相同 _id 的文档。

当这种情况发生时,其中一个会失败。这意味着您必须等待数据库返回成功或错误(通过调用 GetLastError 或通过将写入问题设置为方式。

【讨论】:

【参考方案2】:

不,它一点也不差,事实上内置的ObjectId 在索引中相当大,所以如果你认为你有更好的东西,那么非常欢迎你更改_id 的默认值字段到任何地方。

但是,这是一个很大的但是,在决定放弃使用默认公式 ObjectId 时有一些注意事项,尤其是在使用自动递增 _ids 时,如下所示:https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field

多线程并不是什么大问题,因为findAndModify 和原子锁实际上可以解决这个问题,但是你只是遇到了第一个问题。 findAndModify 不是最快的功能,也不是最轻的功能,经常使用它时性能明显下降。

您也必须考虑自己执行此操作的开销,即使没有findAndModify。对于每个插入,您都需要一个额外的查询。想象一下,有一个唯一的 id,您必须在每次要插入时查询其唯一性。最终,您的插入率会下降到爬行状态,并且您的锁定时间会增加。

当然,ObjectId 非常擅长保持唯一性,而无需在插入之前通过触摸数据库来检查或制定自己的唯一性,因此它没有这种开销。

如果您仍然觉得整数 _id 适合您的场景,那就去尝试吧,但请记住上面描述的开销。

【讨论】:

只是指出如果您使用 mongodb 搜索文档存储库并且您选择了现代且闪电般快速的 simhash 方法,使用 simhash uint64 作为 _id 实际上是理想的;因为您正在搜索,所以无论如何您只会要求 simhash,并且由于您使用 simhash 进行索引,因此您将始终使用“获取或创建”模式添加到索引中,这会否定任何负面因素并使您的id 缩小 33%,比较起来更快。【参考方案3】:

我有一个用例:将 _id 替换为 64 位整数,该整数表示用于搜索的文档索引的 simhash。

因为我打算“获取或创建”,提供初始 simhash,并在不存在的情况下创建新记录是完美的。此外,对于任何在谷歌上搜索的人,MongoDB 支持向我解释说 simhashes 绝对适合分片和缩放,甚至比更通用的 ObjectId 更好,因为它们将完美地和内在地在分片之间划分数据,并且您可以获得存储的密钥负空间(uint64 比 objectId 小得多,无论如何都需要存储)。

另外,对于 Google 员工来说,用 objectId 以外的其他东西替换 MongoDB _id 绝对简单:只需创建一个定义了 _id 的对象;如果您愿意,请使用整数。就是这样:Mongo 将简单地使用它。如果您尝试创建具有相同 _id 的文档,您将收到错误消息(E11000/重复键)。所以像我一样,如果你使用 simhashing,这在所有方面都是理想的。

【讨论】:

以上是关于将 MongoDB 中的 _id 类型更改为整数是不是不好?的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 将 _id 更改为 id

将 _id 从 ObjectId 更改为正常的唯一自动增量整数

如何在Mongodb中将字符串数据类型大量更改为int?

如何在 mongoDB 中使用另一种类型的 id

访问VBA参数查询将整数更改为字符串

MongoDB如何将数组中的字段类型从字符串更改为数组并保持原始值