资讯专栏INFORMATION COLUMN

Mongodb 中的 _id 和 ObjectId

xfee / 2947人阅读

摘要:和中存储的文档必须有一个键。这是的创建方式导致的。由于时间戳在前,这意味着大致会按照插入的顺序排列。前字节保证了同一秒钟不同机器不同进程产生的是唯一的。如果驱动程序允许服务器生成,那么将需要多带带的查询,以确定插入的文档中的值。

_id和ObjectId

MongoDB 中存储的文档必须有一个"_id" 键。这个键的值可以是任何类型的,默认是个ObjectId 对象。在一个集合里面,每个文档都有唯一的"_id" 值,来确保集合里面每个文档都能被唯一标识。如果有两个集合的话,两个集合可以都有一个值为123 的"_id" 键,但是每个集合里面只能有一个"_id" 是123 的文档。

ObjectId

ObjectId 是"_id" 的默认类型。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。这是MongoDB 采用ObjectId,而不是其他比较常规的做法(比如自动增加的主键)的主要原因,因为在多个服务器上同步自动增加主键值既费力还费时。MongoDB 从一开始就设计用来作为分布式数据库,处理多个节点是一个核心要求。后面会看到ObjectId 类型在分片环境中要容易生成得多。

ObjectId 使用12 字节的存储空间,每个字节两位十六进制数字,是一个24 位的字符串。由于看起来很长,不少人会觉得难以处理。但关键是要知道这个长长的ObjectId 是实际存储数据的两倍长。

如果快速连续创建多个ObjectId,会发现每次只有最后几位数字有变化。另外,中间的几位数字也会变化(要是在创建的过程中停顿几秒钟)。这是ObjectId 的创建方式导致的。12 字节按照如下方式生成:

前4 个字节是从标准纪元开始的时间戳,单位为秒。这会带来一些有用的属性。时间戳,与随后的. 5 个字节组合起来,提供了秒级别的唯一性。由于时间戳在前,这意味着ObjectId 大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提高效率,但是这个是没有保证的,仅仅是“大致”。这4 个字节也隐含了文档创建的时间。绝大多数驱动都会公开一个方法从ObjectId 获取这个信息。因为使用的是当前时间,很多用户担心要对服务器进行时间同步。其实没有这个必要,因为时间戳的实际值并不重要,只要其总是不停增加就好了(每秒一次)。

接下来的3 字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的ObjectId,不产生冲突。

为了确保在同一台机器上并发的多个进程产生的ObjectId 是唯一的,接下来的两字节来自产生ObjectId 的进程标识符(PID)。

前9 字节保证了同一秒钟不同机器不同进程产生的ObjectId 是唯一的。后3 字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId 也是不一样的。同一秒钟最多允许每个进程拥有2563(16 777 216)个不同的ObjectId。

自动生成_id

前面讲到,如果插入文档的时候没有"_id" 键,系统会自动帮你创建一个。可以由MongoDB 服务器来做这件事情,但通常会在客户端由驱动程序完成。理由如下。

虽然ObjectId 设计成轻量型的,易于生成,但是毕竟生成的时候还是产生开销。在客户端生成体现了MongoDB 的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。这种理念背后的原因是,即便是像MongoDB 这样的可扩展数据库,扩展应用层也要比扩展数据库层容易得多。将事务交由客户端来处理,就减轻了数据库扩展的负担。

在客户端生成ObjectId,驱动程序能够提供更加丰富的API。例如,驱动程序可以有自己的insert 方法,可以返回生成的ObjectId,也可以直接将其插入文档。如果驱动程序允许服务器生成ObjectId,那么将需要多带带的查询,以确定插入的文档中的"_id" 值。

原文:2.6.6 _id和ObjectId

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18937.html

相关文章

  • mongoDB基础篇①】安装与常用操作语句

    摘要:简述与同为数据库但是为数据库而为文档型数据库存储的是文档的二进制化内部执行引擎为解释器把文档存储成结构在查询时转换为对象并可以通过熟悉的语法来操作的安装启动在上直接下载解压运行即可本身是已编译好的二进制可执行文件如果报错说明你的服务器和 简述 mongoDB与redis同为noSql数据库,但是redis为kv数据库(key/value),而mongoDB为文档型数据库存储的是文档(B...

    UCloud 评论0 收藏0
  • MongoDB中的范式与反范式

    摘要:反范式化与范式化相反将每个文档所需的数据都嵌入在文档内部。决定何时采用范式化何时采用反范式化时比较困难的。范式化能够提高数据写入速度,反范式化能够提高数据读取速度。 原文地址:http://pwhack.me/post/2014-06-25-1 转载注明出处 本文摘录自《MongoDB权威指南》第八章,可以彻底回答以下两个问题: http://segmentfault.com/...

    littleGrow 评论0 收藏0
  • Mongodb使用

    摘要:表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。可以用来重命名增加或删除域,也可以用于创建计算结果以及嵌套文档用于过滤数据,只输出符合条件的文档。 1.下载安装 1.1.首先去官网下载mongodb对应版本安装https://www.mongodb.com/download-center      解压到目录 例如:c:/mongo      创建文件夹用于m...

    luxixing 评论0 收藏0
  • [转]mongodb中的populate方法

    摘要:使用可以实现在一个中填充其他的。表示关联注意被关联的的必须是和才有效。封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下方法用法。类型的时,格式如为表示不填充,为时表示填充。类型,可选,指定附加的查询条件。 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其实和ORM(Object Relational...

    ranwu 评论0 收藏0

发表评论

0条评论

xfee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<