MongoDB中的_id和ObjectId
MongoDB中存储的文档必须要有一个_id键,这个键的值可以是任何类型的,默认为ObjectId。
在每个文档里面,_id值是唯一的,这样可以确保在一个集合里每个文档可以被唯一标识。如果是两个集合的话,在不同的集合里文档的_id是可以相同的。
MongoDB为什么要使用ObjectId,而不使用自动增加的主键等其他的常规的方式?
MongoDB从一开始就设计用来做分布式数据库,处理多个节点是核心的要求。ObjectId被设计成轻量型的,不同的机器都能够用全局的唯一的方法生成ObjectId。
ObjectId采用12个字节的存储空间,每个字节2位16进制的数字,组成一个24位的字符串,ObjectId的创建方式如下:
1.前4个字节是从标准纪元开始的时间戳,单位为妙。由于时间戳在前,所以ObjectId会大致按照插入的书序排序。而且这四个字节隐含了文档的创建时间,大多数驱动都会提供方法从ObjectId中获取文档创建时间。
2.接下来的3个字节是主机的唯一标识。通常是主机名的散列值,这样可以保证不同机器产生的ObjectId不会冲突。
3.8,9两个字节表示产生ObjectId的进程表示符。这是为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的。
4.最后三个字节是自动增加的计数器,表示同一个进程同一秒产生的ObjectId也是不一样的。
ObjectId在客户端生由驱动生成,这体现了MongoDB的设计理念:能从服务器端转移到驱动程序来做的就尽量转移。因为扩展应用层比扩展数据库层要容易的多,将事务交由客户端来处理可以减轻数据库扩展的负担。