将MongoDB中的_id类型更改为整数是不是很糟糕?

时间:2012-12-27 12:03:01

标签: ruby-on-rails mongodb mongoid

MongoDB对_id使用ObjectId类型。

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

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

3 个答案:

答案 0 :(得分:23)

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

但是,这是一个很大的但是,在决定放弃默认的_id时会有一些注意事项,特别是在使用如下所示的自动递增_ids时:{ {3}}

多线程并不是一个大问题,因为ObjectId和原子锁实际上可以解决这个问题,但是你只是遇到了第一个问题。 findAndModify不是最快的功能,也不是最轻的功能,并且在定期使用时会发现显着的性能下降。

即使没有findAndModify,你也必须考虑自己这样做的开销。对于您拥有的每个插入,您将需要进行额外的查询。具有唯一ID的图像,您必须查询每次要插入的唯一性,最终您的插入速率将下降到爬行状态,并且您的锁定将会累积。

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

据说这不是世界上最糟糕的想法,如果你认为它适合你的场景,那就去吧,但要记住,如果你不需要自动递增id,那么你可能会有负担。

答案 1 :(得分:9)

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

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

当发生这种情况时,其中一个会失败。这意味着您必须等待数据库返回成功或错误(通过调用GetLastError或将写入问题设置为已确认),这比仅仅发送一次“忘记”中的数据要花费更长的时间方式。

答案 2 :(得分:1)

我有一个用例:将_id替换为一个64位整数,该整数代表要搜索的文档索引的简化形式。

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

另外,对于您的Google员工来说,用objectId以外的其他内容替换MongoDB _id绝对是简单的:只需创建一个已定义_id的对象即可;如果愿意,请使用整数。就是这样:Mongo会简单地使用它。如果您尝试使用相同的_id创建文档,则会收到错误消息(E11000 / Duplicate键)。因此像我一样,如果您正在使用simhashing,那么从各个方面来看,这都是理想的选择。