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

Ruby on rails 将MongoDB中的_id类型更改为整数是否不好?,ruby-on-rails,mongodb,mongoid,Ruby On Rails,Mongodb,Mongoid,MongoDB对_id使用ObjectId类型 如果我把_id设为一个递增的整数会不会很糟糕 (如果您感兴趣,可以使用gem)您可以这样做,但您有责任确保整数是唯一的 MongoDB不像大多数SQL数据库那样支持自动递增字段。当您有一个分布式或多线程应用程序,其中有多个进程和/或线程创建新的数据库条目时,您必须确保它们使用相同的计数器。否则,两个线程可能会尝试在数据库中存储具有相同id的文档 当这种情况发生时,其中一个将失败。这意味着您必须等待数据库返回成功或错误(通过调用GetLastErro

MongoDB对_id使用ObjectId类型

如果我把_id设为一个递增的整数会不会很糟糕


(如果您感兴趣,可以使用gem)

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

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


当这种情况发生时,其中一个将失败。这意味着您必须等待数据库返回成功或错误(通过调用GetLastError或将写关注点设置为已确认),这比简单地发送数据需要更长的时间。

不,这一点也不坏,事实上,内置的
ObjectId
在索引中相当大,因此如果您认为您有更好的东西,那么非常欢迎您将
\u id
字段的默认值更改为任何值

但是,这是一个大问题,但是,当决定离开默认的
ObjectId
时,有一些考虑因素,特别是当使用如下所示的自动递增ID时:

多线程并不是一个大问题,因为
find和modify
和原子锁实际上可以解决这个问题,但随后您就遇到了第一个问题
findAndModify
既不是最快的功能,也不是最轻的功能,在经常使用它时,会发现性能显著下降

<>你也必须考虑自己做这件事的开销,即使没有<代码> FIDANDATION< <代码>。对于每个插入,您都需要一个额外的查询。想象一下,有一个唯一的id,每次插入时都必须查询该id的唯一性。最终,您的插入速率将下降到爬行状态,并且您的锁定时间将增加

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


如果你仍然觉得整数id适合你的场景,那么就去做吧,但要记住上面描述的开销。

我有一个这样的用例:用64位整数替换整数id,它表示搜索文档索引的simhash

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


另外,对于谷歌用户来说,用objectId以外的东西替换MongoDB id绝对简单:只需创建一个定义了_id的对象;如果愿意,可以使用整数。就是这样:Mongo只需使用它。如果您试图创建一个具有相同_id的文档,您将得到一个错误(E11000/重复密钥)。因此,与我一样,如果您使用simhashing,这在所有方面都是理想的。

这取决于具体情况。有一个参数表示“否”,因为它是唯一的id(自动递增),但还有一个参数表示“是”,因为保持id唯一所需的维护开销(必须查询其他计数器集合)。这就像在插入之前必须检查所有ID的唯一性一样,这最终会阻碍插入速度并造成长时间锁定。嗯,这个简单的功能在DB中有这么多操作=(是的,有很多,因为MongoDB当然没有服务器端自动递增id的概念,你可以在这里寻找制作一个这样的id的方法:事实上,这就是MongoDB不支持这种类型的id服务器端的原因之一。实际上,mongo使用
ObjectID
数据类型作为它的
\u id
ObjectID
是一个12字节是二进制数据,而不是字符串。有关更多信息,请参阅。只要指出,如果您使用mongodb搜索文档repos,并且选择了现代且闪电般快速的simhash方法,那么使用simhash uint64作为_id实际上是理想的;因为您在搜索,您无论如何都只会要求simhash,而且因为您使用的是simhash对于索引,您将始终使用“获取或创建”模式添加到索引中,这将否定任何否定,并使您的ID更小33%,比较速度更快。