ObjectId的值由12个字节组成,其中,性能
ObjectId =时间戳(4字节) + 机器标识码(3字节) + 进程ID(2字节) + 计数器(3字节)spa
ObjectId的构成进程
ObjectId前4个字节存的是时间戳,而时间是递增的,因此ObjectId整体保证递增的顺序。rem
存储的时间戳只精确到秒,在同一台机器不一样的MongoDB进程,同一秒内生成的ObjectId,进程ID小的会排在大的前面。存在这种状况,进程ID大的先生成ObjectId,但仍是会排在进程ID小的后面。因此ObjectId递增不是绝对的。随机数
3个字节所能表达的最大的整数:2^24-1。因此一个MongoDB进程,在一秒内最多能生成 2^24-1 个ObjectId。im
从目前机器的性能来看,要超过这个限制几乎是不可能的。时间戳
ObjectId近似惟一,理论上会出现很小几率(1/(2^24-1))的重复状况,这取决于MongoDB驱动实现ObjectId方式。img
以C#官方驱动来讲,构成ObjectId的计数器,C#使用了Interlocked.Increment实现,保证了同一MongoDB进程在同一秒内生成的多个ObjectId的计数器是累加的,从而保证了生成的ObjectId是惟一的。时间
不过,有些版本的驱动是使用了随机数做为计数器,这种状况下并不能保证生成的ObjectId是惟一的。生成
因此,除非你使用的是一个很是老的版本,或者很小众的驱动,不然都不须要为重复的ObjectId担忧。