BSON ObjectId 占用空间小,可快速生成,可能唯一,可作为document的默认主键。它由12字节组成:
- 4个字节 时间戳,代表ObjectId生成时间,单位是秒
- 3个字节 产生ObjectId的机器识别码
- 2个字节 产生ObjectId的进程id
- 3个字节 以随机数初始化的一个计数器,java驱动以静态变量的形式共享计数器保证同一进程生成的随机数是递增的
注意:如果一秒内有多个进程生成的ObjectId,那么此时生成的ObjectId并不代表数据插入顺序;由于ObjectId由客户端生成的,所以客户端间的时钟偏移也会导致ObjectId顺序混乱
那么自动生成的ObjectId在什么情况下可能重复呢?
- 计数器溢出:同一机器同一客户端在一秒能插入超过16,777,216 (2^24) 的记录
- 非递增的随机计数器:一些驱动可能会使用随机数作为计数器,有1 / 16777216的几率重复。
- 机器和进程id散列冲突:不同的机器和进程生成了同一个hash