mongodb的ObjectId最后三个字节有趣的地方
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最后三个字节有趣的地方的更多相关文章
- MongoDB中ObjectId的误区,以及引起的一系列问题
近期对两个应用进行改造,在上线过程中出现一系列问题(其中一部分是由于ObjectId误区导致的) 先来了解下ObjectId: TimeStamp 前 4位是一个unix的时间戳,是一个int类别,我 ...
- [MongoDB]MongoDB的ObjectId组成
一.ObjectId的组成首先通过终端命令行,向mongodb的collection中插入一条不带“_id”的记录.然后,通过查询刚插入的数据,发现自动生成了一个objectId“5e4fa350b6 ...
- 在UTF-8中,一个汉字为什么需要三个字节?
UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicode为什么会出现就不叙述了,Unicode是针对所有计算机的使用者定义一套统一的编码规范, ...
- 请问utf-8的中文是一个汉字占三个字节长度吗?
这是个好问题,可以当作一个笔试题.先从字符编码讲起. 1.美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0: 2.后来欧洲人发现尼 ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
- 字符集之在UTF-8中,一个汉字为什么需要三个字节?
(一)在UTF-8中,一个汉字为什么需要三个字节? UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicode为什么会出现就不叙述了,Unico ...
- lua去掉字符串中的UTF-8的BOM三个字节
废话不多说,还是先说点吧,项目中lua读取的text文件如果有BOM,客户端解析就会报错,所以我看了看,任务编辑器swGameTaskEditor 在写入文件的时候,也不知道为什么有的文件就是UTF- ...
- 在UTF-8中,一个汉字为什么需要三个字节?(转)
http://www.cnblogs.com/web21/p/6092414.html UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicod ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)-- 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
随机推荐
- 『动善时』JMeter基础 — 7、jmeter.properties文件常用配置
目录 1.默认语言设置 2.配置默认编码格式 3.GUI图标放大比例设置 4.功能区工具栏图标大小设置 5.视图区目录树图标大小设置 6.内容区编辑字体设置 7.添加JMeter元素快捷键设置 8.捕 ...
- [BUUCTF-Pwn]hitcontraining_uaf
[BUUCTF-Pwn]hitcontraining_uaf 以此题作为对Pwn中堆利用的学习的开始.堆题初见,肯定有许多地方理解不恰当,希望师傅们能多多指教. 0x00.简述 成因 应用程序调用fr ...
- Jenkins 基础篇 - 小试牛刀
现在我们来创建一个简单的 Jenkins 任务,这个任务输出 Java 版本信息和系统信息,通过这个任务我们先了解创建 Jenkins 任务的流程,以及了解一些对任务的基础设置,接下来就是演示任务的整 ...
- 企业选择CRM系统的要点
经过十数年的发展,CRM客户管理系统在企业当中开始家喻户晓,它的普及性也越来越高.管理者们也纷纷意识到CRM系统--这种企业管理工具带来的巨大好处.既然CRM给企业带来这么大的好处,那么企业该怎么选择 ...
- margin (子元素远离父元素边框)
如果父盒子没有设置border框着,那么他的子元素无法利用margin-top 来远离父元素的上边框 如果使用了margin-top会使子元素和父元素一起往下移 (子想离,父不设置border边框 则 ...
- java基础——何为方法
方法 java中方法时语句的集合,他们在一起执行一个功能 方法时解决一类问题的步骤的有序组合 方法包含于与类或者对象中 方法在程序中被创建,在其他地方被引用 设计方法的原则:保持其原子性. 就是一个方 ...
- Linux信号与golang中的捕获处理
什么是信号 在计算机科学中,信号是Unix.类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式.它是一种异步的通知机制,用来提醒进程一个事件已经发生. 当一个信号发送给一个进程, ...
- [DB] 大数据集群安装
学习要点 体系架构.原理 多做练习.试验 装虚拟机 网络模式:仅主机模式 software selection:development tools, GUI network & host na ...
- 绿色版 notepad++ 添加鼠标右键菜单
建立一个后缀为 .reg 的注册文件,拷贝以下内容并替换相关路径,保存病双击文件运行加入注册表. Windows Registry Editor Version 5.00 [HKEY_CLASSES_ ...
- DS1302应用电路
http://www.diangon.com/wenku/rd/danpianji/201501/00017904.html