Mongodb 重复Mongo ObjectId的可能性';是在两个不同的集合中生成的吗?
是否可能为两个不同集合中的文档生成相同的Mongo ObjectId?我意识到这绝对是不可能的,但有可能吗 我问的原因不是太具体,而是通过我正在开发的一个应用程序,我们展示了当选官员的公开资料,我们希望这些人能成为我们网站的正式用户。我们为目前不是我们网站成员的用户和当选官员提供了单独的收藏。还有其他各种文件,其中包含有关当选官员的各种数据,所有这些数据都映射回使用当选官员ObjectId的人 创建帐户后,我们仍然会突出显示与当选官员相关的数据,但这些数据现在也是用户集合的一部分,并带有相应的users ObjectId,以将其配置文件映射到与我们的应用程序的交互 几个月前,我们开始将应用程序从MySql转换为Mongo,在转换过程中,我们存储这两种数据类型的传统MySql id,现在我们也开始在用户文档中存储选定的官方Mongo ObjectId,以映射回选定的官方数据 我正在考虑将新用户ObjectId指定为以前选择的官方ObjectId,以使事情更简单,但希望确保不可能与任何现有用户ObjectId发生冲突 谢谢你的洞察力Mongodb 重复Mongo ObjectId的可能性';是在两个不同的集合中生成的吗?,mongodb,database,nosql,Mongodb,Database,Nosql,是否可能为两个不同集合中的文档生成相同的Mongo ObjectId?我意识到这绝对是不可能的,但有可能吗 我问的原因不是太具体,而是通过我正在开发的一个应用程序,我们展示了当选官员的公开资料,我们希望这些人能成为我们网站的正式用户。我们为目前不是我们网站成员的用户和当选官员提供了单独的收藏。还有其他各种文件,其中包含有关当选官员的各种数据,所有这些数据都映射回使用当选官员ObjectId的人 创建帐户后,我们仍然会突出显示与当选官员相关的数据,但这些数据现在也是用户集合的一部分,并带有相应的u
编辑:发布这个问题后不久,我意识到我提出的解决方案不是一个好主意。最好只保留我们现有的模式,并在用户文档中链接到选定的官方“\u id”。对于集合中的ObjectId唯一性没有任何保证。即使可能性很小,但这将是一个非常糟糕的应用程序设计,它依赖于跨集合的_id唯一性 可以在mongo shell中轻松测试这一点:
MongoDB shell version: 1.6.5
connecting to: test
> db.foo.insert({_id: 'abc'})
> db.bar.insert({_id: 'abc'})
> db.foo.find({_id: 'abc'})
{ "_id" : "abc" }
> db.bar.find({_id: 'abc'})
{ "_id" : "abc" }
> db.foo.insert({_id: 'abc', data:'xyz'})
E11000 duplicate key error index: test.foo.$_id_ dup key: { : "abc" }
所以,绝对不要依赖于_id在集合中是唯一的,因为您不控制ObjectId生成函数,所以不要依赖它
可以创建更像uuid的东西,如果手动创建,可以更好地保证唯一性
请记住,您可以将不同“类型”的对象放在同一集合中,那么为什么不将两个“表”放在同一集合中呢。它们将共享相同的id空间,因此保证是唯一的。从“预期”切换到“注册”只需简单地翻转一个字段…ObjectID是以类似于UUID的方式在客户端生成的,但在数据库中具有一些更好的存储属性,例如大致增加顺序并免费编码其创建时间。对于您的用例来说,关键的一点是,即使它们是在不同的机器上生成的,它们的设计也能保证高概率的唯一性 现在,如果您通常引用_id字段,我们不需要跨集合的唯一性,因此可以安全地重用旧的_id。作为一个具体的示例,如果您有两个集合,
colors
和fruits
,则这两个集合都可以同时具有类似{u id:'orange'}
的对象
如果您想了解更多有关如何创建ObjectID的信息,请参阅规范:简短回答 仅对您的初始问题添加一个直接的回答:是的,如果您使用BSON对象ID生成,那么对于大多数驱动程序来说,ID几乎肯定会在集合中是唯一的。“几乎肯定”的含义见下文 长答案 Mongo DB驱动程序生成的BSON对象ID在集合中很可能是唯一的。这主要是因为ID的最后3个字节,对于大多数驱动程序,它是通过静态递增计数器生成的。该计数器是独立于收集的;这是全球性的。例如,Java驱动程序使用随机初始化的静态AtomicInteger 那么,为什么在Mongo文档中,他们说ID“很可能”是唯一的,而不是直接说它们是唯一的呢?在您无法获得唯一ID的情况下,可能会出现三种情况(如果有更多,请告诉我): 在此讨论之前,请记住BSON对象ID包括: [4字节自历元起秒,3字节机器哈希,2字节进程ID,3字节计数器] 以下是三种可能性,因此您可以自己判断被骗的可能性: 1) 计数器溢出:计数器中有3个字节。如果在同一台计算机上、同一进程中,在一秒钟内插入了超过16777216(2^24)个文档,则可能会使递增计数器字节溢出,并最终导致两个对象ID共享相同的时间、计算机、进程和计数器值 2) 计数器非递增:一些Mongo驱动程序对计数器字节使用随机数而不是递增数。在这些情况下,有1/16777216的机会生成非唯一ID,但前提是这两个ID是在同一秒(即,在ID的时间段更新到下一秒之前)在同一台机器上以相同的过程生成的 3) 将计算机和进程哈希设置为相同的值。在某些极不可能的情况下,机器ID和进程ID值可能映射到两台不同机器的相同值。如果发生这种情况,并且两台不同机器上的两个计数器同时在同一秒钟内生成相同的值,那么您将得到一个重复的ID 这是需要注意的三种情况。场景1和场景3看起来不太可能,如果使用正确的驱动程序,场景2是完全可以避免的。您必须检查驱动程序的来源才能确定 万一有人