ObjectId 由12个字节组成,其中组成如下:

a 4-byte timestamp value, representing the ObjectId’s creation, measured in seconds since the Unix epoch

a 5-byte random value

a 3-byte incrementing counter, initialized to a random value

前4个字节为以秒为单位的时间戳

中间5个字节为随机字符串

最后3个字节是一个随机数,并且递增

3个字节24位,也就是1秒内生成2的24次,即16777216个不重复的ObjectId。

但是请看文档中的描述,incrementing counter, initialized to a random value

当时我看到这里就想,为什么不能从0开始呢,比如某一秒的第一个 ObjectId 是5ebc0b522d5c8f0c0c【000000】,接着是5ebc0b522d5c8f0c0c【000001】5ebc0b522d5c8f0c0c【000002】 ... 一直到最大值,然后下一秒,又是从【000000】开始。

因为如果使用随机数,那么有可能某一秒的第一个 ObjectId 是5ebc0b522d5c8f0c0c【fffffe】,那接下来这一秒还需要生成 ObjectId,岂不是溢出了,不能用了?

后来实验了一下,发现不是我想象的那样。

在 shell 中执行 db.foo.insertOne({ t: "t" }),发现随机数的递增与时间戳无关,也就是当前连接第一次生成随机数后,后面执行的操作都会使用这个随机数递增,而不会生成另一个随机数。

第一次执行,生成ObjectId如 {这一秒的时间戳}{随机字符串}28c060

下一个ObjectId => {这一秒的时间戳}{随机字符串}28c061

下一个ObjectId => {这一秒的时间戳}{随机字符串}28c062

......

一直到最大值,然后再从 000000 开始算起

所以 mongodb 确实是能在1秒内生成不重复的16777216个ObjectId

注意,随机字符串在同一个 shell 连接中是相同的。

插个题外话:mongodb从3.4版本开始,中间5个字节就已经改为随机字符串了,而不是3个字节表示机器标识码+2个字节表示进程号。至于为什么,官网没说,可以看其他开发者的猜想

mongodb的ObjectId最后三个字节有趣的地方的更多相关文章

  1. MongoDB中ObjectId的误区,以及引起的一系列问题

    近期对两个应用进行改造,在上线过程中出现一系列问题(其中一部分是由于ObjectId误区导致的) 先来了解下ObjectId: TimeStamp 前 4位是一个unix的时间戳,是一个int类别,我 ...

  2. [MongoDB]MongoDB的ObjectId组成

    一.ObjectId的组成首先通过终端命令行,向mongodb的collection中插入一条不带“_id”的记录.然后,通过查询刚插入的数据,发现自动生成了一个objectId“5e4fa350b6 ...

  3. 在UTF-8中,一个汉字为什么需要三个字节?

    UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicode为什么会出现就不叙述了,Unicode是针对所有计算机的使用者定义一套统一的编码规范, ...

  4. 请问utf-8的中文是一个汉字占三个字节长度吗?

    这是个好问题,可以当作一个笔试题.先从字符编码讲起. 1.美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0: 2.后来欧洲人发现尼 ...

  5. 搭建高可用mongodb集群(三)—— 深入副本集内部机制

    在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...

  6. 字符集之在UTF-8中,一个汉字为什么需要三个字节?

    (一)在UTF-8中,一个汉字为什么需要三个字节? UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicode为什么会出现就不叙述了,Unico ...

  7. lua去掉字符串中的UTF-8的BOM三个字节

    废话不多说,还是先说点吧,项目中lua读取的text文件如果有BOM,客户端解析就会报错,所以我看了看,任务编辑器swGameTaskEditor 在写入文件的时候,也不知道为什么有的文件就是UTF- ...

  8. 在UTF-8中,一个汉字为什么需要三个字节?(转)

    http://www.cnblogs.com/web21/p/6092414.html UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicod ...

  9. 搭建高可用mongodb集群(三)—— 深入副本集内部机制

    在上一篇文章<搭建高可用mongodb集群(二)-- 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...

随机推荐

  1. Google Hacking的用法

    目录 Google Hacking 基本搜索 高级搜索 Index of inurl Google Hacking Google Hacking 是利用谷歌搜索的强大,来在浩瀚的互联网中搜索到我们需要 ...

  2. 7.PHP Cookie与Session

    Cookie与Session Cookie Cookie功能 创建cookie <?PHP    setcookie("TMCookie" ,'www.baidu.com') ...

  3. 【python】Leetcode每日一题-笨阶乘

    [python]Leetcode每日一题-笨阶乘 [题目描述] 通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积.例如,factorial(10) = 10 * 9 * 8 * 7 * 6 ...

  4. Insert Pictures In Hexo Blog

    After build my blog following the online course step by step , I began to try to write my own blog️ ...

  5. 正则表达式:(mysql)REGEXP

    检索列prod_name包含文本1000的所以行 SELECT prod_name FROM  products WHERE prod_name REGEXP '1000' ORDER BY prod ...

  6. Nmap浅析(2)——端口发现

    端口发现 ​ 每台网络设备最多有216(65536)个端口,端口的作用是实现"一机多用".操作系统分了65536个端口号,程序在发送的信息中加入端口号,操作系统在接收到信息后按照端 ...

  7. Go的Waitgroup和锁

    学 Go 的时候知道 Go 语言支持并发,最简单的方法是通过 go 关键字开启 goroutine 即可.可在工作中,用的是 sync 包的 WaitGroup,然而这样还不够,当多个 gorouti ...

  8. Blazor实现未登录重定向到登录页的方法

    今天研究了一下blazor,发现他默认启动就是类似于后台管理系统的界面,看到这个页面我就想给他写个登录,有登录就涉及到未登录重定向的问题,但是我没有找到blazor全局路由的设置,知道的老哥可以告诉我 ...

  9. FFmpeg应用实践之命令查询

    0. 前言 FFmpeg 中常用的工具有三个,分别是多媒体编解码工具ffmpeg.多媒体内容分析工具ffprobe和多媒体播放器ffplay.本文介绍的指令都是与编解码工具 ffmpeg 相关的. 学 ...

  10. 四种方式带你层层递进解剖算法---hash表不一定适合寻找重复数据

    一.题目描述 找出数组中重复的数字 > 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次. ...