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. Webpack5构建速度提升令人惊叹,早升级早受益

    为什么要升级? webpack4用的好好的,运行稳定,为什么要升级到webpack5, 每次升级,都要经历一场地震,处理许多loader和plugin API的破坏性改变. 请给我们一个充分的升级理由 ...

  2. VS2019解决X64无法内联汇编的问题

    策略:VC编译器x64平台不支持内联汇编,我们利用在Source文件中直接添加asm文件,直接在asm文件中写汇编代码,然后将asm文件编译为OBJ文件.然后就可以在c++文件中声明asm文件中的函数 ...

  3. 逆向工程初步160个crackme-------6

    工具:1. 按钮事件地址转换器E2A 2. PEID 3. Ollydbg 同样我们先来运行一下这个程序, ok按钮是被禁用的,有一个help按钮点击后弹出一个消息框:消息框显示提示信息为.本程序需要 ...

  4. SparkSQL电商用户画像(五)之用户画像开发(客户基本属性表)

    7.电商用户画像开发 7.1用户画像--数据开发的步骤 u 数据开发前置依赖 -需求确定 pv uv topn -建模确定表结构 create table t1(pv int,uv int,topn ...

  5. MindSpore模型验证

    技术背景 在前面一篇博客中,我们介绍了MindSpore在机器学习过程中保存和加载模型的方法.这种将模型存储为静态文件的做法,使得我们可以更灵活的使用训练出来的模型,比如用于各种数据集的验证,或者是迁 ...

  6. 17.继承 and18.接口和多态 内部类 匿名内部类,Lambda表达式

    1. 继承 1.1 继承的实现(掌握) 继承的概念 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法 实现继承的格式 继承通过extends实现 ...

  7. JAVA并发(2)-ReentrantLock的见解

    上节,我们讲了AQS的阻塞与释放实现原理,线程间通信(Condition)的原理.这次,我们就讲讲基于AQS实现的ReentrantLock(重入锁). 1. 介绍 结合上面的ReentrantLoc ...

  8. C++知识点案例 笔记-5

    1.关系运算符重载 2.类型转换函数重载 3.转换构造函数 4.函数模板 5.显式实例化 6.类模板外定义模板函数 1.关系运算符重载 ==关系运算符重载== //直接(按分数)比较两个对象 #inc ...

  9. www.heihei.work站长日记

    ____________2020-03-30_________________晴 昨天刚加的游客IP统计选取一部分查了下地址,小朋友你是不是有很多问号??? 36.99.136.142河南 电信 47 ...

  10. Docker存储(4)

    一.docker存储资源类型 用户在使用 Docker 的过程中,势必需要查看容器内应用产生的数据,或者需要将容器内数据进行备份,甚至多个容器之间进行数据共享,这必然会涉及到容器的数据管理 (1)Da ...