![MongoDB进阶与实战:微服务整合、性能优化、架构管理](https://wfqqreader-1252317822.image.myqcloud.com/cover/697/38209697/b_38209697.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
3.3 ObjectId生成器
MongoDB集合中所有的文档都有一个唯一的_id字段,作为集合的主键。在默认情况下,_id字段使用ObjectId类型。如下面的代码:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_56_4.jpg?sign=1738855778-P3nv8oK7oEqftSCtVFh82W5r100YBdNf-0-30d3476b18ff5493d20e7985290cd5e0)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_57_1.jpg?sign=1738855778-95l5sEnYqNierQXhmudMxEYW1QTQ3B9v-0-18bc45477792b2be72cfaf1eaa3fbaad)
这里的_id是自动生成的,其中"5d15767ff4531cb8062f3c93"是ObjectId的16进制编码形式,该字段总共为12个字节。
为了避免文档的_id字段出现重复,ObjectId被定义为3个部分:
● 4字节表示Unix时间戳(秒)。
● 5字节表示随机数。
● 3字节表示计数器(初始化时随机)。
由此可见,经过多个字段随机组合后,出现重复的概率是极低的。
对于新插入集合中的文档,如果没有包含_id字段,则数据库服务器会自动生成一个新的ObjectId。但实际上,大多数客户端驱动都会自行生成这个字段,比如MongoDB Java Driver会根据插入的文档是否包含_id字段来自动补充ObjectId对象。这样做不但提高了离散性,还可以降低MongoDB服务器端的计算压力。另外,在ObjectId的组成中,5字节的随机数并没有明确定义,客户端可以采用机器号、进程号来实现,如图3-2所示。
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_57_2.jpg?sign=1738855778-xnfNxVZBhstLYJBFtD7rVP1JNorEvVS9-0-36c271391269389db7d631430d153de3)
图3-2 ObjectId结构
ObjectId具体如何生成,可以参考下面的代码:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_57_3.jpg?sign=1738855778-XmemMhEq6HnbUIjBklp1ybKv9j7q8mu9-0-c47e83802aa5bbf7e87c082a1f267990)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_58_1.jpg?sign=1738855778-5BDTDVCn6zhIL42NhHoe74jmr6HVGb7q-0-f2e48e87de0d0c475cac57e277378695)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_59_1.jpg?sign=1738855778-OxInzXBFdjGD0ASt9KQQWROc4Ftv4fUs-0-82e682f91de39c7f0ed8634ee31e3797)
以上代码来自MongoDB Java Driver(3.6.2版本)。当然,具体应用也可以使用自动生成的_id,但必须保证_id的唯一性。