【问题标题】:ObjectIDs and uniqueness within a collection集合中的 ObjectID 和唯一性
【发布时间】:2019-06-21 14:55:57
【问题描述】:

所以这是一个思想实验:

mongo 中的 ObjectID 有 24 个字符,因此如果您使用它们构建 URI,它会变得很麻烦。

每个字符都以 16 为基数,因此,如果我们得到最后 8 位数字,它将允许我们进行 16^8 (4,294,967,296) 个唯一组合。

根据ObjectID specification,它由以下组成:

一个 4 字节的值,表示自 Unix 纪元以来的秒数,
一个 5 字节的随机值,
一个 3 字节的计数器,以随机值开头。

是否可以保证,在一个集合中,如果我们使用最后 4 个字节 - 8 个字符 - 每个文档都有一个唯一值?

这样我就可以在模型上创建一个 .id 属性,在 .pre('save') 上分配它,并在该属性上为集合创建一个索引。

我已经测试并确认它适用于 12,856,767 个文档,并计划对其进行彻底测试,但想知道专家的意见,我完全不同意吗?

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    根据 mongodb ObjectID 的文档:

    虽然 ObjectId 值应随时间增加,但它们不会 必然单调。这是因为他们:

    • 仅包含一秒的时间分辨率,因此在同一秒内创建的 ObjectId 值没有保证顺序,并且
    • 由客户端生成,可能具有不同的系统时钟。

    因此,简而言之,当涉及到 ObjectId 时,您无法 100% 保证唯一性。基本上,存在冲突的可能性,特别是对于同一主机在同一秒内大量生成的 ObjectID。 在几乎所有情况下(正如您在 13M 记录中也看到的那样),这不是问题,但仍有机会......

    但是,mongo 实例中的Timestamp保证是唯一的

    BSON 有一个特殊的时间戳类型供内部 MongoDB 使用,而不是 与常规日期类型相关联。时间戳值是 64 位 价值在哪里:

    前 32 位是 time_t 值(自 Unix 纪元以来的秒数) 第二个 32 位是一个递增序数 给第二个。

    在单个 mongod 实例中,时间戳值始终是唯一的。

    虽然它明确指出这是针对internal use,但如果您追求真正独特的价值,您可能需要考虑一下。

    【讨论】:

    • Akrion 我知道如果同时创建多个项目,时间戳位可以重复,但我没有使用这些位,我使用的是一些“随机”位和顺序那些...
    • 我不是在争论,我只是想弄清楚这一点:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 2014-03-24
    • 2012-08-27
    • 2015-10-10
    • 2021-12-29
    • 2011-02-18
    相关资源
    最近更新 更多