MongoDB作为目前排名最高的非关系型数据库(目前排名第四),作为排名第一的文档型数据库,涉及到了一些原来没有的概念和术语,为了深入了解MongoDB,需要逐步了解清楚这些概念和术语。
ObjectId
作为文档型数据库,MongoDB数据库的每个文档必须有一个"_id"字段,这个字段拥有唯一值,并且自动生成,是主键。这个唯一的值就是ObjectId。
ObjectId是12个字节的BSON类型,构成如下:
ObjectId的组成 | |||||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
时间戳 | 机器标识符 | 进程ID | 计数器 | ||||||||
54f92930 | b82f19 | 9305 | 541bcf | ||||||||
54f92930b82f199305541bcf |
- 时间戳:前4个字节,生成ObjectId时的时间戳(秒级);
- 机器标识符:再三个字节,MongoDB所在主机的标识符,一般为主机名称的hash值,这样不同的主机就有不同的标识符,同一台主机上的不同MongoDB实例生成的ObjectId机器标识符是一样的,但是在多主机的分布式环境中,机器标识符来保障ObjectId的不冲突。
- 进程ID:再两个字节,PID,机器标识符确保在分布式环境中不同的主机上生成的ObjectId不冲突,而进程ID来确保在同一台主机上,多个MongoDB进程生成的ObjectId不冲突。
- 计数器:再三个字节,前面的九个字节确保了在不同机器不同的MongoDB进程在一个时间戳(1秒)生成的ObjectId不冲突,最后这三个字节来确保在一个时间戳内(1秒内)生成的ObjectId不冲突。
ObjectId的组成完美的解决了分布式环境下高并发情况下的主键唯一性的问题。在类似的应用场景中,可以学习借鉴。
ObjectId示例:
> mongo
MongoDB shell version: 3.0.0
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> use TonySharpMongoDB
switched to db TonySharpMongoDB
> db.TonySharpCollection.insert({Name:"Tony",Key:"MongoDB3.0"})
WriteResult({ "nInserted" : 1 })
> db.TonySharpCollection.find()
{ "_id" : ObjectId("54f92930b82f199305541bcf"), "Name" : "Tony", "Key" : "MongoD
B3.0" }