返回顶部
首页 > 资讯 > 数据库 >理解MongoDB默认的ObjectID
  • 913
分享到

理解MongoDB默认的ObjectID

2024-04-02 19:04:59 913人浏览 泡泡鱼
摘要

BSON ObjectID Specification A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (secon

BSON ObjectID Specification

A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (seconds since epoch), a 3-byte Machine id, a 2-byte process id, and a 3-byte counter. Note that the timestamp and counter fields must be stored big endian unlike the rest of BSON. This is because they are compared byte-by-byte and we want to ensure a mostly increasing order. The fORMat:

 

0 1 2 3 4 5 6 7 8 9 10 11
time machine pid inc

 

  • TimeStamp. This is a unix style timestamp. It is a signed int representing the number of seconds before or after January 1st 1970 (UTC).
  • Machine. This is the first three bytes of the (md5) hash of the machine host name, or of the mac/network address, or the virtual machine id.
  • Pid. This is 2 bytes of the process id (or thread id) of the process generating the object id.
  • Increment. This is an ever incrementing value, or a random number if a counter can't be used in the language/runtime.

BSON ObjectIds can be any 12 byte binary string that is unique; however, the server itself and almost all drivers use the format above.

分段查看ObjectId的指令及结果如下:

  1. > db.test.findOne()._id.toString()  
  2. ObjectId("50c6b336ba95d7738d1042e3")  
  3. > db.test.findOne()._id.toString().substring(10,18)  
  4. 50c6b336  
  5. > db.test.findOne()._id.toString().substring(18,24)  
  6. ba95d7  
  7. > db.test.findOne()._id.toString().substring(24,28)  
  8. 738d  
  9. > db.test.findOne()._id.toString().substring(28,34)  
  10. 1042e3 

ObjectId占用12字节的存储空间,由“时间戳” 、“机器名”、“PID号”和“计数器”组成。使用机器名的好处是在分布式环境中能够避免单点计数的性能瓶颈。使用PID号的好处是支持同一机器内运行多个monGod实例。最终采用时间戳和计数器的组合来保证唯一性。

时间戳

确保ObjectId唯一性依赖的是时间的顺序,不依赖时间的取值,因此集群节点的时间不必完全同步。既然ObjectId已经有了时间戳,那么在文档中就可以省掉一个时间戳了。在使用ObjectID提取时间时,应注意到mongoDB允许各节点时间不一致这一细节。

下面是查看时间戳的两种写法:

  1. > db.test1.findOne()._id.getTimestamp()
  2. ISODate("2012-12-12T03:52:45Z")
  3. > Date(parseInt(db.test1.findOne()._id.toString().substring(10,18),16))
  4. Wed Dec 12 2012 12:11:02 GMT+0800

机器名

机器名通过Md5加密后取前三个字节,应该还是有重复概率的,配置生产集群时检查一下总不会错。另外,我也注意到重启MongoDB后MD5加密结果会发生变化,在利用ObjectID提取机器名信息时需格外注意。

PID号

注意到每次重启mongod进程后PID号通常会发生变化就可以了。

计数器

计数器占3个字节,表示的取值范围就是256*256*256-1=16777215。不妨认为MongDB性能的极限是单台设备一秒钟插入一千万条记录。以目前的水平看,单台设备一秒钟插入一万条就很不错了,因此ObjectID计数器的设计是够用的。

循环插入了一些记录,下面的查询中b是循环计数器,可以看出我机器上的ObjectId计数器是按顺序增加的:

  1. > parseInt(db.test.findOne({b:1000})._id.toString().substring(28,34),16)  
  2. 1947382  
  3. > parseInt(db.test.findOne({b:1001})._id.toString().substring(28,34),16)  
  4. 1947383  
  5. > parseInt(db.test.findOne({b:1002})._id.toString().substring(28,34),16)  
  6. 1947384  
  7. > parseInt(db.test.findOne({b:1003})._id.toString().substring(28,34),16)  
  8. 1947385 

以下代码源自:Http://www.cnblogs.com/xjk15082/arcHive/2011/09/18/2180792.html

  1. 构建objectId   
  2.  public class ObjectId implements Comparable<ObjectId> , java.io.Serializable {  
  3.  final int _time;  
  4.      final int _machine;  
  5.      final int _inc;  
  6.  boolean _new;  
  7.    
  8.  public ObjectId(){  
  9.          _time = (int) (System.currentTimeMillis() / 1000);  
  10.          _machine = _genmachine;  
  11.          _inc = _nextInc.getAndIncrement();  
  12.          _new = true;  
  13.  }  
  14.  ……  
  15.  } 
  1. 机器码和进程码的生成  
  2.  private static final int _genmachine;  
  3.  static {  
  4.  try {  
  5.  final int machinePiece;  
  6.          {  
  7.  StringBuilder sb = new StringBuilder();  
  8.              Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();  
  9.              while ( e.hasMoreElements() ){  
  10.                  NetworkInterface ni = e.nextElement();  
  11.                  sb.append( ni.toString() );  
  12.              }  
  13.              machinePiece = sb.toString().hashCode() << 16;  
  14.              LOGGER.fine( "machine piece post: " + Integer.toHexString( machinePiece ) );  
  15.  }  
  16.  final int processPiece;  
  17.          {  
  18.              int processId = new java.util.Random().nextInt();  
  19.              try {  
  20.  processId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode();  
  21.  }catch ( Throwable t ){  
  22.  }  
  23.  ClassLoader loader = ObjectId.class.getClassLoader();  
  24.              int loaderId = loader != null ? System.identityHashCode(loader) : 0;  
  25.  StringBuilder sb = new StringBuilder();  
  26.              sb.append(Integer.toHexString(processId));  
  27.              sb.append(Integer.toHexString(loaderId));  
  28.              processPiece = sb.toString().hashCode() & 0xFFFF;  
  29.              LOGGER.fine( "process piece: " + Integer.toHexString( processPiece ) );  
  30.          }  
  31.  _genmachine = machinePiece | processPiece;  
  32.          LOGGER.fine( "machine : " + Integer.toHexString( _genmachine ) );  
  33.      }catch ( java.io.IOException ioe ){  
  34.          throw new RuntimeException( ioe );  
  35.      }  
  36.  } 

 

您可能感兴趣的文档:

--结束END--

本文标题: 理解MongoDB默认的ObjectID

本文链接: https://lsjlt.com/news/38602.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 理解MongoDB默认的ObjectID
    BSON ObjectID Specification A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (secon...
    99+
    2024-04-02
  • mongodb如何修改默认端口
    mongodb修改默认端口的方法:1、win环境中,以管理员权限打开cmd命令符窗口,进入到安装mongodb数据库的bin目录下,并输入“mongod --dbpath 数据库路径 --port 端口号”命令修改即可;2、linux环境中...
    99+
    2024-04-02
  • 怎么查看mongodb默认时区
    要查看MongoDB的默认时区,可以执行以下步骤:1. 打开MongoDB的shell命令行界面。2. 输入以下命令:```db.r...
    99+
    2023-08-30
    mongodb
  • python 默认编码的理解与设置
     原链接: http://notewo.sinaapp.com/blog/full_article/blogid=54   python 里面的编码和解码,就是unicode  和str 这两种形式的相对转换。 编码: uni...
    99+
    2023-01-31
    python
  • angular中默认路由的理解用法详解
    目录0.前言1.路由的功能及原理2.默认路由的使用0.前言 前一段时间折腾angular的路由折腾的够呛, 这篇文章简单介绍一下自己的理解及用法。 1.路由的功能及原理 一开始并不理...
    99+
    2024-04-02
  • vue默认插槽的理解与实例代码
    目录什么是插槽默认插槽的理解代码片段总结什么是插槽 插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符...
    99+
    2024-04-02
  • MongoDB学习笔记:默认数据库与集合
    本文更新于2022-01-15,使用MongoDB 4.4.5。 目录adminsystem.usersconfigchangelogchunkscollectionsdatabaseslockssettingsshardstagsloc...
    99+
    2018-04-08
    MongoDB学习笔记:默认数据库与集合
  • 详解python中的defaultdict 默认值
    目录前言语法setdefault()和defaultdict()的区别setdefault()defaultdict()前言 在字典中查找某一个值的时候,若key不存在就会返回一个k...
    99+
    2023-05-16
    defaultdict 默认值 python defaultdict 默认值
  • Python中的默认参数详解
    文章的主题 不要使用可变对象作为函数的默认参数例如 list,dict,因为def是一个可执行语句,只有def执行的时候才会计算默认默认参数的值,所以使用默认参数会造成函数执行的时候一直在使用同一个对象,引起bug。 基本原理 在 ...
    99+
    2023-01-31
    详解 参数 Python
  • Apache默认解析后缀
    Apache HTTP服务器默认情况下支持解析以下常见的文件扩展名: HTML文件.htmlHTML文件.htmServer Side Includes (SSI) HTML文件.shtml PHP脚本文件.phpPHP脚本文件.php3P...
    99+
    2023-10-06
    服务器 运维
  • 如何理解ol和ul的padding和margin默认值
    本篇内容主要讲解“如何理解ol和ul的padding和margin默认值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解ol和ul的padding和mar...
    99+
    2024-04-02
  • 关于对TypeScript泛型参数的默认值理解
    目录泛型简介举个举个泛型参数的默认值——函数重载泛型参数的默认值——正文参考泛型简介 软件工程中,我们不仅要创建一致的定义良好的 AP...
    99+
    2024-04-02
  • redis默认端口是6379的理由
    小编给大家分享一下redis默认端口是6379的理由,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名...
    99+
    2024-04-02
  • Spring Data默认值的错误解决
    目录源码解析修正Spring Data有很多配置的默认值,但不一定都适合你。如一个依赖Cassandra 的项目,有时写入数据后,并不能立马读到。这种错误并没有什么报错,一切都是正常...
    99+
    2023-01-17
    Spring Data默认值 Spring Data默认值配置
  • C++之默认参数详解
    目录一、C++ 默认参数1.举例1.单个参数2.多个参数2.规则总结一、C++ 默认参数 通常情况下,函数在调用时,形参从实参那里取得值。对于多次调用同一函数同一实参时,C++给出了...
    99+
    2024-04-02
  • Android9.0的默认配置
    前言 Android系统的一些默认配置,需要根据客户的需求进行具体的配置。在这里记录Android9.0的一些默认配置方法。 方法论 在源码中寻...
    99+
    2022-06-06
    默认 Android
  • phpmyadmin数据库管理工具的默认用户名和密码默认是什么
    小编给大家分享一下phpmyadmin数据库管理工具的默认用户名和密码默认是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!p...
    99+
    2024-04-02
  • 切换默认python版本(解决ROS中python默认版本为python2的问题)
    1.前言 许多小伙伴在安装完ROS以后,需要基于python3写ROS程序(尤其是部署深度学习算法),但是ROS默认的python版本为python2,导致无法兼容一些基于python3写的算法。有的小伙伴会选择利用anaconda来创建p...
    99+
    2023-09-28
    linux ubuntu 嵌入式硬件
  • vue默认插槽的理解及实例代码是怎样的
    vue默认插槽的理解及实例代码是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。什么是插槽插槽就是子组件中的提供给父组件使用的一个占位符,用<slot...
    99+
    2023-06-21
  • kubernetes需要默认的serviceaccount的原因解析
    目录什么是k8s的serviceAccount?为什么每一个ns下都有默认的sa?default sa yaml默认的sa下都会挂一个secret,这个secret是从哪里来的?一道...
    99+
    2023-05-18
    kubernetes serviceaccount
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作