MongoDB中的_id和ObjectId
ObjectId是"_id"的默认类型。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。
这是MongoDB采用ObjectId,而不是其他比较常规的做法(比如自动增加的主键)的主要原因,因为在多个
服务器上同步自动增加主键值既费力还费时。MongoDB从一开始就设计用来作为分布式数据库,处理多个节
点是一个核心要求。后面会讲到ObjectId类型在分片环境中容易生成得多。
ObjectId使用12字节的存储空间,每个字节两位十六进制数字,是一个24位的字符串。由于看起来很长,不
少人会觉得难以处理。但关键是要知道这个长长的ObjectId是实际存储数据的两倍长。
如果快速连续创建多个ObjectId,会发现每次只有最后几位数字有变化。另外中间的几位数字也会变化(要
是在创建的过程中停顿几秒钟)。这是ObjectId的创建方式导致的。12字节按照如下方式生成:
0|1|2|3 |
4|5|6 |
7|8 |
9|10|11
时间戳 |
机器 |
PID |
计数器
前4字节是从标准纪元开始的时间戳,单位为秒。这会带来一些有用的属性。
时间戳,与随后的5个字节组合起来,提供了秒级别的唯一性。
由于时间戳在前,这意味着ObjectId大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提
高效率,但是这个是没有保证的,仅仅是"大致"。这4个字节也隐含了文档创建的时间。绝大多数驱动都会公开
一个方法从ObjectId获取这个信息。
因为使用的是当前时间,很多用户担心要对服务器进行时间同步,其实这个没有必要,因为时间戳的实际值并不
重要,只要其总是不停增加就好了(每秒一次)。
接下来的三个字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的
ObjectId,不产生冲突。
为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的。后3个字节就是一个自动增加的计数器,确
保相同进程同一秒产生的ObjectId也是不一样的。同一秒钟最多允许每个进程拥有256(16777216)个不同的ObjectId。
2.自动生成_id
前面讲到,如果插入文档的时候没有"_id"键,系统会帮你自动创建一个。可以由MongoDB服务器来做这件事情,但
通常会在客户端由驱动程序完成。理由如下:
虽然ObjectId设计成轻量型的,易于生成,但是毕竟生成的时候还是产生开销。在客户端生成体现了MongoDB的设计
理念:能从服务器端转移到驱动程序来做的事,就尽量转移。这种理念背后的原因是,即便是像MongoDB这样的可扩
展数据库,扩展应用层也要比扩展数据库层容易的多。将事务交由客户端来处理,就减轻了数据库扩展的负担。
在客户端生成ObjectId,驱动程序能够提供更加丰富的API。例如,驱动程序可以有自己的insert方法,可以返回生
成的ObjectId,也可以直接将其插入文档。如果驱动程序允许服务器生成ObjectId,那么将需要单独的查询,以确
定插入的文档中的"_id"值。
转载:http://blog.csdn.net/magneto7/article/details/2384294
MongoDB中的_id和ObjectId的更多相关文章
- mongodb中的_id的ObjectId的生成规则
MongoDB中存储的文档必须有一个"_id" .这个键值可以是任何类型,默认是ObjectID对象.在一个集合里,每个文档都有一个唯一的“_id”,确保集合里的每个文档都能被唯一 ...
- MongoDB中_id(ObjectId)生成
MongoDB 中我们经常会接触到一个自动生成的字段:"_id",类型为ObjectId. 之前我们使用MySQL等关系型数据库时,主键都是设置成自增的.但在分布式环境下,这种方法 ...
- 用nodejs删除mongodb中ObjectId类型数据
mongodb中"_id"下面有个ObjectId类型的数据,想通过这个数据把整个对像删除,费了半天劲终于搞定费话少说上代码 module.exports = function ( ...
- MongoDB中ObjectId的误区,以及引起的一系列问题
近期对两个应用进行改造,在上线过程中出现一系列问题(其中一部分是由于ObjectId误区导致的) 先来了解下ObjectId: TimeStamp 前 4位是一个unix的时间戳,是一个int类别,我 ...
- java 查询 mongodb 中的objectid
网上找了很久查询objectid的方法都是错的,用mongovue能查询出来,但就是用java不知道怎么查询 1.mongovue里的查询方式: {"_id" : ObjectId ...
- MongoDB中insert方法、update方法、save方法简单对比
MongoDB中insert方法.update方法.save方法简单对比 1.update方法 该方法用于更新数据,是对文档中的数据进行更新,改变则更新,没改变则不变. 2.insert方法 该方法用 ...
- 使用aggregate在MongoDB中查找重复的数据记录
我们知道,MongoDB属于文档型数据库,其存储的文档类型都是JSON对象.正是由于这一特性,我们在Node.js中会经常使用MongoDB进行数据的存取.但由于Node.js是异步执行的,这就导致我 ...
- 在MongoDB中实现聚合函数 (转)
随着组织产生的数据爆炸性增长,从GB到TB,从TB到PB,传统的数据库已经无法通过垂直扩展来管理如此之大数据.传统方法存储和处理数据的成本将会随着数据量增长而显著增加.这使得很多组织都在寻找一种经济的 ...
- mongodb中分页显示数据集的学习
这次继续看mongodb中的分页.首先依然是插入数据: 1) db.Blog.insert( { name : "Denis", age : 20, city : "P ...
随机推荐
- Redis之面试题总结
缓存雪崩 缓存穿透 缓存与数据库双写一致 最后 随着系统访问量的提高,复杂度的提升,响应性能成为一个重点的关注点.而缓存的使用成为一个重点.redis 作为缓存中间件的一个佼佼者,成为了面试必问项目. ...
- mysql truncate 与 delete的相同点和不同点
相同点 都可以清空表,自增字段将起始值恢复成1 [delete from table_name where 1 可以保持自增的最大值] delete from table_name; truncate ...
- 基于linux与busybox的reboot命令流程分析
http://www.xuebuyuan.com/736763.html 基于Linux与Busybox的Reboot命令流程分析 ********************************** ...
- python爬虫练习之批量下载zabbix文档
# -*- coding: UTF-8 -*- import requests,re,time url = 'https://www.zabbix.com/documentation/3.4/zh/m ...
- 08Response
1.功能:设置响应消息 1. 设置响应行 1. 格式:HTTP/1.1 200 ok 2. 设置状态码:setStatus(int sc) 2. 设置响应头:setHeader(String name ...
- Memcached快速入门
1.基本概念 基于高性能的key-value的内存数据库.单进程多线程,协议简单,使用文本行的协议,支持数据类型简单,不支持持久化,轻量级锁CAS机制,集群互不通信,缓存策略(LRU,FIFO,LFU ...
- C语言/C++知识
<C与指针>pdf 下载: 新浪微盘: https://vdisk.weibo.com/s/A6gkKkHrGH0g
- [转]C++引用
引用的概念 引用:就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符 &引用名=目标变量名: 如下:定义引用ra,它是变量a的引用,即别名. i ...
- buuctf@ciscn_2019_en_2
from pwn import * context.log_level='debug' io=process('./ciscn_2019_en_2') libc=ELF('./libc.so') el ...
- 微信小游戏egret开发包括p2引擎小结
用egret + p2 做一个类似投球的小游戏,坑大致如下: 1.p2引擎与egret坐标不同注意转换,横坐标没什么,纵坐标egret.y = stageHeight - body.position[ ...