MongoDB的ObjectId是如何生成的?

ktecyv1j  于 2022-11-28  发布在  Go
关注(0)|答案(6)|浏览(183)

它们是不是有点随机?
我的意思是...人们能把它们分开吗?

fiei3ece

fiei3ece1#

它们不是随机的,很容易预测:
BSON ObjectID是一个12字节的值,由4字节的时间戳(自纪元以来的秒数)、3字节的计算机ID、2字节的进程ID和3字节的计数器组成
http://www.mongodb.org/display/DOCS/Object+IDs

xoshrz7s

xoshrz7s2#

下面是MongoDB对象ID(http://jsfiddle.net/icodeforlove/rN3zb/)的JavaScript实现

function ObjectIdDetails (id) {
    return {
        seconds: parseInt(id.slice(0, 8), 16),
        machineIdentifier: parseInt(id.slice(8, 14), 16),
        processId: parseInt(id.slice(14, 18), 16),
        counter: parseInt(id.slice(18, 24), 16)
    };
}

因此,如果你有足够多的对象,它们会泄露大量有关基础设施的信息,而且你还知道所有对象的创建日期。
IE:你有多少台服务器,每台服务器运行多少个进程。

pgx2nnw8

pgx2nnw83#

它们通常是由驱动程序本身在客户端生成的。例如,在ruby中,BSON::ObjectID可以使用:

  • https://github.com/mongodb/bson-ruby/blob/master/lib/bson/object_id.rb#L369

您还可以生成自己的ObjectId。如果要使用业务标识符,这一点尤其有用。

断裂性

  • 使用驱动程序生成的ObjectId时,为低
  • 当使用自己的业务ID时,根据其可预测性(登录、连续标识符......)略高
vxbzzdmp

vxbzzdmp4#

MongoDB数据库驱动程序默认生成一个ObjectID标识符,分配给每个文档的_id字段。在许多情况下,ObjectID可以用作应用程序中的唯一标识符。
ObjectID是一个96位数字,其组成如下:
一个4字节的值,表示自Unix纪元以来的秒数(直到2106年才会用完秒数)
3字节机器标识符(通常从MAC地址派生),
一个2字节的进程ID,以及
3字节计数器,从随机值开始。

mccptt67

mccptt675#

来自MongoDB官方文件links
它显示:
对象识别码
ObjectId很小,可能是唯一的,生成速度快,并且是有序的。ObjectId值由12个字节组成,其中前四个字节是反映ObjectId创建的时间戳。具体来说:
一个4字节的值,表示自Unix纪元以来的秒数,
5字节随机值,以及
3字节计数器,从随机值开始。
在MongoDB中,存储在集合中的每个文档都需要一个unique_id字段作为主键,如果插入的文档省略了_id字段,MongoDB驱动程序会自动为_id字段生成一个ObjectId。

rdlzhqv9

rdlzhqv96#

MongoDB database drivers by default generate an ObjectID identifier that is assigned to the _id field of each document. In many cases the ObjectID may be used as a unique identifier in an application.
总计12个字节:

  • 4字节的时间戳值,表示Unix纪元以来的秒数(直到2106年才会用完秒数)
  • 5字节随机值,以及
  • 3字节递增计数器,从随机值开始。

来自mongo-go-driver的示例:

var objectId [12]byte

    // 4 bytes unix time-stamp second (big endian)
    binary.BigEndian.PutUint32(objectId[0:4], uint32(timestamp.Unix()))

    // global random number generated by driver 
    copy(objectId[4:9], processUnique[:])
    
    // global counter by driver
    putUint24(objectId[9:12], atomic.AddUint32(&objectIDCounter, 1))

相关问题