【问题标题】:How is a MongoDB ObjectID 12 bytes?MongoDB ObjectID 12 字节如何?
【发布时间】:2019-10-08 03:31:00
【问题描述】:

据我所知,MongoDB 中的字符串以 UTF-8 格式存储,因此每个字符的长度在 1 到 4 个字节之间。

MongoDB documentation says the following about ObjectID:

返回一个新的 ObjectId 值。 12 字节的 ObjectId 值包括:

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

在一个示例中,它显示ObjectId("507f1f77bcf86cd799439011")。这个字符串在 UTF-8 中是 24 个字节,所以我不明白 12 个字节在哪里起作用。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    根据ObjectId documentation,您看到的字符串是 12 个字节的十六进制表示。它不是Unicode,甚至不是字符串。它实际上是一个数字。

    一个字节是 8 位,这意味着它可以有 2^8 == 256 个可能的值(请参阅Byte)。

    如何简洁地表示具有 256 个可能值的数字?将其表示为 16^2 怎么样?您可以通过使用 2 个十六进制值(以 16 为基数)来实现此目的。您唯一需要发明的是一个编号系统,它可以使用 16 而不是 10。

    事实上,我们使用从af 的字母来表示值10 到15。

    因此,一个字节可以用两个十六进制数表示。它恰好使用af,因为我们懒得为它们发明特殊符号。它们不是字母。它们是数字。

    所以不,您在 ObjectId 中看到的字符串不代表 24 个字节。每 2 个字符代表一个字节。 24 个十六进制数 == 12 个字节。

    【讨论】:

      【解决方案2】:

      作为@kevinadi 答案的补充,让我们稍微检查一下下面显示的 ArrayBuffer 代码,以反映 12 个字节的 ObjectId 反映的表示,其中每个索引字符(元素、字符 - 在此特定上下文中都是同义词 ) 在我们选择的 TypedArray 中处于“2 BYTES_PER_ELEMENT”的条件下。据我认为MongoDB 12 bytes ObjectId + 4 个未使用的索引分配在固定大小的 TypedArray 组成 16 字节(十六进制方法),如果没有压缩,这将相当于 24 个元素 + 8 个未使用的索引分配(总共 32 个) .在场景的每个部分 2 乘以 16 (MongoDB ObjectId is presented in hexadecimal string) 等于 32 。简单的数学,对吧?现在让我们来看看 ArrayBuffer 在使用 TypedArray 时的可能解释,选择模拟分配与压缩的过程以及它们的属性: .length.byteLength 分别:

      const init_buffer = new ArrayBuffer(16); // init allocation
      const uint8_inst1 = new Uint8Array(init_buffer);
      const uint8_inst2 = new Uint16Array(uint8_inst1);
      console.log("2 BYTES_PER_ELEMENT i.e. 2 times less than total quantity of characters available [compressed approach]: ", uint8_inst2.length);
      console.log("How many characters in total available [uncompressed approach]: ", uint8_inst2.byteLength);

      【讨论】:

        猜你喜欢
        • 2018-03-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 2012-08-12
        • 2022-10-21
        • 2019-08-07
        • 2021-04-26
        • 1970-01-01
        相关资源
        最近更新 更多