【问题标题】:Creating custom Object ID in MongoDB在 MongoDB 中创建自定义对象 ID
【发布时间】:2021-10-24 14:48:10
【问题描述】:

我正在创建一个服务,我将使用 MongoDB 作为存储后端。 该服务将生成用户输入的哈希,然后查看我们的数据集中是否已经存在相同的哈希(+ 输入)。

哈希将是唯一的但随机的(= 非增量/顺序),所以我的问题是:

  1. 对象 ID 使用随机值是否合法?示例:

$object_id = new MongoId(HEX-OF-96BIT-HASH);

或者 MongoDB 会以不同于其他服务器生成的 ObjectID 的方式处理 ObjectID,因为“真实”的 ObjectID 还包含时间戳、machine_id 等?

使用“随机”值的优缺点是什么?我猜当新的 _id 不以任何方式递增时,引擎更新插入索引的速度在统计上会变慢 - 我对此是否正确?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    是的,对对象 id 使用随机值是完全可以的,如果正在存储的文档的 _id 字段中存在某个值,则将其视为 objectId。

    由于_id字段总是被索引,并且主键,你需要确保为每个对象生成不同的objectid。 有一些指南可以优化用户定义的对象 ID:

    https://docs.mongodb.com/manual/core/document/#the-id-field.

    【讨论】:

    • 唯一 + 随机 ID 是要走的路。
    • @Sim 这就是你投反对票的原因吗?也许你可以向我们解释一下你的理由,你基本上和我和这个回答者所说的理由一样。本质上,ObjectId 是一个唯一且随机的 id。
    • @Sammaye 抱歉,这一定是一次针对性不强的点击。 :/我想对你和这个答案都投赞成票,因为它们比我的更相关。如果您编辑答案,我可以投票。没有编辑系统不会让我。
    • @Sim ah ok :) 您应该能够单击向下箭头,然后单击向上箭头而不进行编辑,但我为拼写错误提供了一个小编辑
    • @Sim 这只是部分答案。如果您希望数据大小增长到足以使分片成为必要,那么您的 ID 不按顺序增加就非常重要。分片使用对象 ID 的第一个字节进行分片。例如,如果您的唯一 id 是基于时间的(就像许多内置“随机 id”函数的语言一样),即使使用散列,从分片的角度来看,您的 id 仍然是连续的,在扩展时可能会导致巨大的性能瓶颈。 Node 的 'shortid' npm 是一个非常棒的非顺序唯一 ID 存储库。这也有一个 PHP 端口。
    【解决方案2】:

    虽然任何值(包括哈希值)都可用于 _id 字段,但出于两个原因,我建议不要使用随机值:

    1. 如果您为两个不同的对象生成相同的随机值,您可能需要制定冲突管理策略。在问题中,您暗示您将使用某种类型的哈希算法生成 ID。我不会认为这些值是“随机的”,因为它们是基于您使用散列消化的内容。那么,冲突的概率是内容的多样性和散列算法的函数。如果您使用的是 MD5 或 SHA-1 之类的东西,我不会担心算法,只担心您正在散列的内容。如果您需要制定冲突管理策略,那么您绝对不应该使用随机或基于哈希的 ID,因为集群环境中的冲突管理很复杂并且需要额外的查询。

    2. 随机值和散列值有意分散在数轴上。 (a) 将需要更多的 B-tree 索引始终保存在内存中,并且 (b) 由于 B-tree 重新平衡,可能会导致可变的插入性能。 MongoDB 针对处理 ObjectID 进行了优化,这些 ObjectID 以升序排列(以一秒时间粒度)。你最好还是坚持下去。

    【讨论】:

      【解决方案3】:

      我刚刚找到了一个关于索引性能的问题的答案:

      如果 _id 的顺序有些明确,则不需要加载 _id 索引的整个 b 树。 BSON ObjectIds 有这个属性。

      来源:http://www.mongodb.org/display/DOCS/Optimizing+Object+IDs

      【讨论】:

      • 啊,是的,我刚刚注意到那个问题实际上有两个问题,哎呀抱歉:​​)
      • 删除了我的第一条评论,因为我改变了主意,加载整个 b-tree 将是一件坏事,我还重申了之前针对基于范围的查询的跳过问题。
      【解决方案4】:

      它的好坏取决于它的独特性。当然,MongoDB 提供的 ObjectId 是非常独特的,所以这是一件好事。只要您可以复制这种独特性,就可以了。

      使用您自己的 ID 没有固有的风险/性能损失。我猜想以字符串形式使用它可能会消耗更多的索引/存储/查询能力,但是您以 MongoID (ObjectId) 形式使用它应该保留不将其存储在简单字符串中的优势。

      【讨论】:

        猜你喜欢
        • 2016-12-15
        • 2020-06-28
        • 2017-12-04
        • 1970-01-01
        • 2018-04-19
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多