在 MongoDB 中 ObjectId 使用 12 字节的存储空间,是一个由 24 个 16 进制数字组成的字符串(每个字节可以存储两个 16 进制数字)。ObjectId 通常用于记录的唯一主键。
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
字节 | 描述 |
---|---|
1 - 4 字节 | 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时。 |
5 - 7 字节 | 机器标识码。 |
8 - 9 字节 | 由进程 id 组成 PID。 |
10 - 12 字节 | 随机数。 |
MongoDB ObjectId 的具体组成,图解如下:
Time
时间戳。objectid 的前 4 位进行提取然后按照十六进制转为十进制,这个数字就是一个时间戳。通过时间戳的转换,就成了易看清的时间格式。
Machine
机器。接下来的三个字节就是机器码,这三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器 hash 值,确保在分布式中不造成冲突,这也就是在同一台机器生成的 objectId 中间的字符串都是一模一样的原因。
PID
进程 ID。上面的 Machine 是为了确保在不同机器产生的 objectId 不冲突,而 pid 就是为了在同一台机器不同的 mongodb 进程产生了 objectId 不冲突。
INC
自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成 objectId 不冲突,这后面的三个字节是一个自动增加的计数器,用来确保在同一秒内产生的 objectId 也不会发现冲突,允许 256 的 3 次方等于 16777216 条记录的唯一性。
总的来看,objectId 的前 4 个字节时间戳,记录了文档创建的时间;接下来 3 个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的 objectId;后 2 个字节的进程 id,决定了在同一台机器下,不同 mongodb 进程产生不同的 objectId;最后通过 3 个字节的自增计数器,确保同一秒内产生 objectId 的唯一性。ObjectId 的这个主键生成策略,很好地解决了在分布式环境下高并发情况主键唯一性问题,值得学习借鉴。
在 MongoDB 中 ObjectId 使用 12 字节的存储空间,是一个由 24 个 16 进制数字组成的字符串(每个字节可以存储两个 16 进制数字)。ObjectId 通常用于记录的唯一主键。