• MongoDB 使用 ObjectId 代替时间


    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
  • 相关阅读:
    [汇编与C语言关系]1.函数调用
    深入理解计算机系统
    设计模式
    深度探索C++对象模型
    More Effective C++
    MySQL必知必会
    数据结构与算法分析
    Java编程思想(后)
    Java编程思想(前十章)
    Java 入门
  • 原文地址:https://www.cnblogs.com/jay54520/p/9207635.html
Copyright © 2020-2023  润新知