An ObjectId is a 12-byte unique identifier consisting of:

  • a 4-byte value representing the seconds since the Unix epoch,
  • a 3-byte machine identifier,
  • a 2-byte process id, and
  • a 3-byte counter, starting with a random value.

由于前 4 个 byte 表示时间,所以 ObjectId 可以反映时间。默认情况下,前 4 个 byte 表示的时间为文件创建时服务器的时间。

如果你使用 ObjectId 代替时间,那么导入过去存在的数据时 ObjectId 可能发生冲突[1]。

针对同一时刻创建 ObjectId

根据过去的某一时刻创建 ObjectId 会重复,因为前 3 种 byte 都一样,只有最后 3 个 byte 不一样。

对于 PyMongo Driver:

from bson import ObjectId

# timestamp
str(ObjectId())[:8]
'5b2b0778'
str(ObjectId())[:8]
'5b2b0779' # machine id 和 process id
str(ObjectId())[8:18]
'0e118bd5c7'
str(ObjectId())[8:18]
'0e118bd5c7' # counter
str(ObjectId())[18:]
'a5b135'
str(ObjectId())[18:]
'a5b136'

假如针对 timestamp 5b2b0778 生成订单,由于是同一机器、进程,所以前 3 种 byte 都相同。而最后的 counter 是在进程启动时初始化一个随机值,然后进行递增。任意两个 ObjectId 相同的概率为 1677 万分之一:

# 3 byte 为 24 位
2 ** 24 / 10000
1677

但随着订单的增多,冲突的概率会越来越大。

所以不能采用针对某一时刻创建 ObjectId 的方法。

分散创建

设定一个时间区间,然后将文件分散到每一秒创建。如果时间区间足够大,那么效果就和正常创建 ObjectId 一样。时间区间可以根据理想冲突率和文件数倒推出来。

参考

  1. https://dzone.com/articles/using-and-abusing-mongodb

MongoDB 使用 ObjectId 代替时间的更多相关文章

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

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

  2. 从MongoDB的ObjectId中获取时间信息

    MongoDB默认使用_id字段作为主键,类型为ObjectId.ObjectId的生成有一定的规则,详情可以查看这篇文章 - MongoDB深究之ObjectId.如果你在写入数据库的时候忘记写入创 ...

  3. 线上mongodb 数据库用户到期时间修改的操作记录

    登陆版权数据库,显示"此用户已到期",数据库使用的是mongodb,顾 需要将此用户的到期时间延长. 解决过程: 1)到网站对应tomcat配置里找出等里mongodb的信息(mo ...

  4. [MongoDB]MongoDB的ObjectId组成

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

  5. MongoDB的ObjectId和基本操作增删改查(3)

    ObjectId 基本操作增删改查 增: insert 介绍: mongodb存储的是文档,. 文档是json格式的对象. 语法: db.collectionName.insert(document) ...

  6. 用nodejs删除mongodb中ObjectId类型数据

    mongodb中"_id"下面有个ObjectId类型的数据,想通过这个数据把整个对像删除,费了半天劲终于搞定费话少说上代码 module.exports = function ( ...

  7. mongoDB _id:ObjectId("xxxx")详解

     http://blog.haohtml.com/archives/10678   MongoDB ObjectId的优化  

  8. mvc使用mongodb时objectId序列化与反序列化

    前面有写使用自己的mvc 序列化工具即jsonNetResult.我这里结合之前写的jsonNetResult来做一个Json序列化工具,而且序列化ObjectId成一个字符串.详细代码例如以下 us ...

  9. mongodb的ObjectId最后三个字节有趣的地方

    ObjectId 由12个字节组成,其中组成如下: a 4-byte timestamp value, representing the ObjectId's creation, measured i ...

随机推荐

  1. Windows API中的坑

    本文主页链接:Windows API中的坑 ExpandEnvironmentStrings 风险: 进程会继承其父进程的环境变量.在展开如%APPDATA%等文件夹时,有可能父进程对此环境变量进行过 ...

  2. json对象与json字符串互转方法

    jQuery插件支持的转换方式: 复制代码 代码如下: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 ...

  3. 01、Windows Store APP 设置页面横竖屏的方法

    在 windows phone store app 中,判断和设置页面横竖屏的方法,与 silverlight 中的 Page 类 不同,不能直接通过 Page.Orientation 进行设置.而是 ...

  4. 使用JSTL的sql:query标签制作分页查询遇到NoSuchFieldError: deferredExpression

    参考:http://hi.baidu.com/desyle/item/4fe650265792d7182a0f1c33 症状: 如题所述,代码如下 <sql:query var="re ...

  5. windows下wim配置成IDE

    1.配置文件_wimrc set fileencodings=utf-,ucs-bom,cp936,big5 set fileencoding=utf- source $VIMRUNTIME/vimr ...

  6. Windows Phone Unit Test 环境搭建

    单元测试对工程质量带来的作用就不详细说明了,本文只讨论如何在WP开发环境下搭建测试工程     历史 从WP7时代官方是不支持UnitTest工程的,因此需要采用WPToolkitTest这个工程来实 ...

  7. 基于HTML5自定义文字背景生成QQ签名档

    分享一款利用HTML5实现的自定义文字背景应用,首先我们可以输入需要显示的文字,并且为该文字选择一张背景图片,背景图片就像蒙版一样覆盖在文字上.点击生成QQ签名档即可将文字背景融为一体生成另外一张图片 ...

  8. swift侧开菜单

    此文来自学习这篇博客后的学习笔记,原博客是用oc写的,我最近在学swift,于是改写为swift. swift和oc之间互相调用还是很方便的,但是要注意AnyObject和optional的运用,我现 ...

  9. Qt 中彩色图像转换为灰度图

    近期在做几个图像处理相关的项目.里面有一个操作就是须要先将彩色图像转换为灰度图像. QImage 有一个convertToFormat方法.最開始一直用这个函数来实现. 可是今天细致看了看,发现这个函 ...

  10. 简单实现Spring中BeanFactory原理

    上一篇文章介绍了Java反射机制在Spring IOC中的应用,知道了BeanFactory底层的实现原理. 原理搞懂了,对Spring IOC理解起来也很容易. 先来看看Java代码获取Spring ...