文档章节

MongoDB中的_id和ObjectId介绍

一书生
 一书生
发布于 2016/06/30 15:40
字数 1099
阅读 98
收藏 0

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

ObjectId

ObjectId_id的默认类型。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。这是MongoDB采用ObjectId,而不是其他比较常规的做法(比如自动增加的主键)的主要原因,因为在多个服务器上同步自动增加主键值既费力又费时。因为设计MongoDB 的初衷就是用作分布式数据库,所以能够在分片环境中生成唯一的标示符非常重要。

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

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

0 1 2 34 5 67 89 1 0 1 1
时间戳机器PID计数器

ObjectId的前4个字节是从标准纪元开始的时间戳,单位为秒。这会带来一些有用的属性。

  • 时间戳,与随后的5字节(稍后介绍)组合起来,提供了秒级别的唯一性。
  • 由于时间戳在前,这意味着ObjectId大致会按照插入的顺序排列。这对于某些方面很有用,比如可以将其作为索引提高效率,但是这个是没有保证的,仅仅是“大致”。
  • 这4字节也隐含了文档创建的时间。绝大多数驱动程序都会提供一个方法,用于从ObjectId获取这些信息。

因为使用的是当前时间,很多用户担心要对服务器进行时钟同步。虽然在某些情况下,在服务器间进行时间同步确实是个好主意,但是这里其实没有必要,因为时间戳的实际值并不重要,只要它总是不停增加就好了(每秒一次)。

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

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

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

自动生成_id

前面讲到,如果插入文档时没有_id键,系统会自动帮你创建一个。可以由MongoDB服务器来做这件事,但通常会在客户端由驱动程序完成。这一做法非常好地体现了MongoDB 的哲学:能交给客户端驱动程序来做的事情就不要交给服务器来做。这种理念背后的原因是,即便是像MongoDB这样扩展性非常好的数据库,扩展应用层也要比扩展数据库层容易得多。将工作交由客户端来处理,就减轻了数据库扩展的负担。

© 著作权归作者所有

共有 人打赏支持
一书生
粉丝 3
博文 13
码字总数 5030
作品 0
浦东
高级程序员
初识MongoDB-用法和用途

用意:记录一下自己学习MongoDB的一些体会. 适合范围, 安装和用法. 一. MongoDB相关 JavaScript统一天下 JavaScript正在快节奏地统一整个web开发流程. JvaScript是WEB前端开发的唯一依靠, 依赖...

清风漫步
2014/02/21
0
0
mongodb配置主从(官方已经不建议使用)

官方网站: http://www.mongodb.org/ 关于mongodb的主从,官方已经不建议使用,目前建议使用副本集; 但由于公司现有环境的原因,如果改用副本集,则需要修改数据,受限于现实的种种原因,只...

邱野
06/28
0
0
Linux下的Mongodb部署应用梳理

一、Mongodb简介 官网地址:http://www.mongodb.org/ MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。MongoDB 是一个介于关系数据库和非关系数据库之...

拎壶冲冲冲
08/15
0
0
如何使用MongoDB+Springboot实现分布式ID

如何实现分布式id,一般会给出这几种方案 使用数据库自增Id 使用reids的incr命令 使用UUID Twitter的snowflake算法 利用zookeeper生成唯一ID MongoDB的ObjectId mongodb如何实现分布式ID Mo...

小贱是个程序员
06/05
0
0
MongoDB的sharding功能

MongoDB的auto-sharding功能是指mongodb通过mongos自动建立一个水平扩展的数据库集群系统,将数据库分表存储在sharding的各个节点上。 一个mongodb集群包括一些shards(包括一些mongod进程)...

underA
2013/09/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Java中生成比特币钱包地址

让我们通过学习比特币(Bitcoin)如何实施该技术的各个方面来工作,好吗?该技术包括以下几个方面: 比特币地址bitcoin address是用来发送和接收比特币的。 交易transaction是比特币从一个地...

geek12345
12分钟前
0
0
面试必备Linux基础知识

学习Linux之前,我们先来简单的认识一下操作系统。 一 从认识操作系统开始 1.1 操作系统简介 我通过以下四点介绍什么操作系统: 操作系统(Operation System,简称OS)是管理计算机硬件与软件...

小小明童鞋
13分钟前
2
0
SpringBoot基础教程3-1-3 Quartz定时任务单点持久化

1 概述 实际项目中,复杂的定时任务都会结合持久化,动态改变定时任务状态,本文将介绍基于Quartz的定时任务单点持久化方式,通过RESTful风格,演示定时任务的CRUD,最后使用Swagger测试。 ...

Mkeeper
29分钟前
3
0
Android入门—文件目录解析

AndroidManifest.xml 是每个android程序中必须的文件,它位于整个项目的根目录。我们每天都在使用这个文件,往里面配置程序运行所必要的组件,权限,以及一些相关信息。但是对于这个文件,我...

haoyuehong
32分钟前
5
0
IDEA中Maven打包时如何跳过测试

方法1:直接使用IDEA提供的方式 Maven命令栏的工具栏有下图中的图标,上面就写着 Skip Tests 按下图标后,如下图,test就不可用了 直接使用package命令即可。 方法2:自己编辑maven命令 进入...

karma123
46分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部