日期:2014-05-16 浏览次数:20407 次
在MongoDB中,如果不特别指定,每个文档都会生成一个唯一的ObjectId作为其主键_id的值。这个值是一个看似随机的串。这个串到底是什么值?为什么MongoDB要使用这个值作为默认主键?它内部又包含了什么样的信息?如果你还不了解,就请看下面文章吧。
感谢刘浩@人民搜索的投稿。
MongoDB中数据的基本单元称为文档(Document)。文档是MongoDB的核心概念,多个键极其关联的值有序的放置在一起便是文档。
在一个特定集合内部,需要唯一的标识文档。因此MongoDB中存储的文档都由一个”_id”键,用于完成此功能。这个键的值可以是任意类型的,默认试ObjectId对象。ObjectId对象的生成思路是本文的主题,也是很多分布式系统可以借鉴的思路。
为了考虑分布式,“_id”要求不同的机器都能用全局唯一的同种方法方便的生成它。因此不能使用自增主键(需要多台服务器进行同步,既费时又费力),因此选用了生成ObjectId对象的方法。
ObjectId使用12字节的存储空间,其生成方式如下:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
时间戳 | 机器ID | PID | 计数器 |
前四个字节时间戳是从标准纪元开始的时间戳,单位为秒,有如下特性:
机器ID是服务器主机标识,通常是机器主机名的散列值。
同一台机器上可以运行多个mongod实例,因此也需要加入进程标识符PID。
前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId的唯一性。后三个字节是一个自动增加的计数器(一个mongod进程需要一个全局 的计数器),保证同一秒的ObjectId是唯一的。同一秒钟最多允许每个进程拥有(256^3 = 16777216)个不同的ObjectId。
总结一下:时间戳保证秒级唯一,机器ID保证设计时考虑分布式,避免时钟同步,PID保证同一台服务器运行多个mongod实例时的唯一性,最后的计数器保证同一秒内的唯一性(选用几个字节既要考虑存储的经济性,也要考虑并发性能的上限)。
“_id”既可以在服务器端生成也可以在客户端生成,在客户端生成可以降低服务器端的压力。
?
http://blog.nosqlfan.com/html/3511.html
?
?
?