草庐IT

mongodb - 在两个不同的集合中生成重复的 Mongo ObjectId 的可能性?

coder 2023-10-26 原文

是否可以为两个不同集合中的文档生成完全相同的 Mongo ObjectId?我意识到这绝对不太可能,但有可能吗?

Without getting too specific, the reason I ask is that with an application that I'm working on we show public profiles of elected officials who we hope to convert into full fledged users of our site.我们为当前不是我们网站成员的用户和民选官员提供了单独的收藏。还有各种其他文档包含有关民选官员的各种数据,这些数据都映射回使用民选官员 ObjectId 的人。

After creating the account we still highlight the data that's associated to the elected official but they now also are a part of the users collection with a corresponding users ObjectId to map their profile to interactions with our application.

几个月前,我们已经开始将我们的应用程序从 MySql 转换为 Mongo,在转换过程中,我们为这两种数据类型存储了遗留的 MySql id,现在我们也开始存储选定的官方 Mongo ObjectId在用户文档中映射回选定的官方数据。

我正在考虑将新用户 ObjectId 指定为之前选出的官方 ObjectId 以使事情变得更简单,但我想确保不会与任何现有用户 ObjectId 发生冲突。

感谢您的见解。

编辑:发布这个问题后不久,我意识到我提出的解决方案不是一个好主意。最好只保留我们现有的当前架构,并只链接到用户文档中选定的官方“_id”。

最佳答案

简答题

只是添加对您最初问题的直接回应:是的,如果您使用 BSON 对象 ID 生成,那么<​​em>对于大多数驱动程序,ID 几乎肯定会在集合中是唯一的。请参阅下文了解“几乎可以肯定”的含义。

长答案

Mongo DB 驱动程序生成的 BSON 对象 ID 很可能在集合中是唯一的。这主要是因为 ID 的最后 3 个字节,对于大多数驱动程序 是通过静态递增计数器生成的。该计数器是独立于集合的;它是全局性的。例如,Java 驱动程序使用随机初始化的静态 AtomicInteger。

那么,为什么在 Mongo 文档中,他们说 ID“极有可能”是唯一的,而不是直截了本地说它们将是唯一的?如果您无法获得唯一 ID,可能会出现三种情况(如果有更多情况,请告诉我):

在此讨论之前,回想一下 BSON 对象 ID 包括:

[自纪元以来 4 字节秒,3 字节机器哈希,2 字节进程 ID,3 字节计数器]

这里有三种可能性,所以你自己判断被骗的可能性有多大:

1) 计数器溢出:计数器有3个字节。如果您碰巧在同一台机器上的同一进程中在一秒钟内插入超过 16,777,216 (2^24) 个文档,那么您可能会溢出递增的计数器字节并最终得到两个共享同一时间的对象 ID,机器、进程和计数器值。

2) 计数器非递增:一些 Mongo 驱动程序使用随机数而不是计数器字节的递增数。在这些情况下,有 1/16,777,216 的机会生成非唯一 ID,但前提是这两个 ID 在同一秒内生成(即在 ID 更新到下一秒的时间段之前),在同一时间机器,在同一过程中。

3) 机器和进程散列为相同的值。在极不可能的情况下,机器 ID 和进程 ID 值可能会映射到两台不同机器的相同值。如果发生这种情况,并且两台不同机器上的两个计数器同时在同一秒内生成相同的值,那么您将得到一个重复的 ID。

以下是需要注意的三种情况。情况 1 和 3 似乎不太可能,如果您使用正确的驱动程序,情况 2 是完全可以避免的。您必须检查驱动程序的来源才能确定。

关于mongodb - 在两个不同的集合中生成重复的 Mongo ObjectId 的可能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15127710/

有关mongodb - 在两个不同的集合中生成重复的 Mongo ObjectId 的可能性?的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  5. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  6. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  7. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

  8. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  9. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  10. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

随机推荐