一日三省吾身

博客园 首页 联系 订阅 管理

不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍。

下表将帮助您更容易理解Mongo中的一些概念:

SQL术语/概念MongoDB术语/概念解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins   表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

通过下图实例,我们也可以更直观的的了解Mongo中的一些概念:

数据库

一个mongodb中可以建立多个数据库。

MongoDB的默认数据库为"db",该数据库存储在data目录中。

MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。

"show dbs" 命令可以显示所有数据的列表。

$ ./mongo
MongoDB shell version: 3.0.6
connecting to: test
> show dbs
local  0.078GB
test   0.078GB
>

执行 "db" 命令可以显示当前数据库对象或集合。

$ ./mongo
MongoDB shell version: 3.0.6
connecting to: test
> db
test
>

运行"use"命令,可以连接到一个指定的数据库。

> use local
switched to db local
> db
local
>

以上实例命令中,"local" 是你要链接的数据库。

在下一个章节我们将详细讲解MongoDB中命令的使用。

数据库也通过名字来标识。数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有' '(空格)、.、$、/、\和\0 (空宇符)。
  • 应全部小写。
  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

文档

文档是一个键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

一个简单的文档例子如下:

{"site":"www.runoob.com", "name":"菜鸟教程"}

下表列出了 RDBMS 与 MongoDB 对应的术语:

RDBMSMongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )
数据库服务和客户端
Mysqld/Oracle mongod
mysql/sqlplus mongo

需要注意的是:

  1. 文档中的键/值对是有序的。
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .和$有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)。

集合

集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。

集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

 

比如,我们可以将以下不同数据结构的文档插入到集合中:

{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.runoob.com","name":"菜鸟教程","num":5}

当第一个文档插入时,集合就会被创建。

合法的集合名

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。 

如下实例:

db.col.findOne()

capped collections

Capped collections 就是固定大小的collection。

它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似。

Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。

 

要注意的是指定的存储大小包含了数据库的头信息。

 

db.createCollection("mycoll", {capped:true, size:100000})
  • 在capped collection中,你能添加新的对象。
  • 能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
  • 数据库不允许进行删除。使用drop()方法删除collection所有的行。
  • 注意: 删除之后,你必须显式的重新创建这个collection。
  • 在32bit机器中,capped collection最大存储为1e9( 1X109)个字节。

元数据

数据库的信息是存储在集合中。它们使用了系统的命名空间:

dbname.system.*

在MongoDB数据库中名字空间 <dbname>.system.* 是包含多种系统信息的特殊集合(Collection),如下:

集合命名空间描述
dbname.system.namespaces 列出所有名字空间。
dbname.system.indexes 列出所有索引。
dbname.system.profile 包含数据库概要(profile)信息。
dbname.system.users 列出所有可访问数据库的用户。
dbname.local.sources 包含复制对端(slave)的服务器信息和状态。

对于修改系统集合中的对象有如下限制。

在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。

{{system.users}}是可修改的。 {{system.profile}}是可删除的。


MongoDB 数据类型

下表为MongoDB中常用的几种数据类型。

数据类型描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。shell默认使用64位浮点型数值。对于整型值,可使用NumberInt类(表示4字节带符号整数),或NumberLong类(表示8字符带符号整数)
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Arrays 用于将数组或列表或多个值存储为一个键。它既能作为有序对象(如列表、栈和队列),也能作为无序对象(如数据集)。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值或者不存在的字段。
Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。它是"_id"默认类型
Binary Data 二进制数据。二进制数据是一个任意字节的字符串,不能直接在shell中使用,如果要将非utf-8字符保存到数据库,二进制数据是唯一方式。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。

Date日期类,创建日期对象时,应使用new Date(...),而非Date(...),如将构造函数(...)作为函数进行调用(即不包括new的方式),返回的是日期的字符串表示,而非日期对象。

ObjectId:它使用12字节的存储空间,是一个由24个十六进制数字组成的字符串,这个长长的ObjectId是实际存储数据的两倍长,ObjectId的12字节按照如下方式生成:

前4个字节是从标准纪元开始的时间戳,单位为妙。1>时间戳:与随后5个字节组合起来,提供了妙级别的唯一性。由于时间戳在前,这意味着ObjectId大致会按照插入的顺序排列(比如可以作为索引提高效率,但是这个没有保证,只是“大致”)。2>、之后的3个字节,是所在主机的唯一标识,通常是机器主机名的散列值(hash),这样就可以确保不同主机生成不同的ObjectId。为了确保同一台机器上并发的多个进程产生的ObjectId是唯一的,接下来得这两个字节来自产生ObjectId的进程的进程标识符(PID)。3>最后4位也隐含了文档的创建时间,绝大多数驱动程序都会提供一个方法,用于从ObjectId获取这些信息。前9字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的,最后3个字节是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是不一样的。一秒钟最多允许每个进程拥有2536个不同的ObjectId。

启动mongodb数据库:

在命令行下输入cmd,到dos窗口,切换到mongodb的安装目录下,然后输入如下命令启动:

需要现在本地新建data和db文件夹。

C:\data\db表示本地存放数据库数据的地方。

通过shell连接MongoDB服务

在启动shell时指定机器名和端口,就可以连接到一台不同的机器(或者端口)。启动mongo shell时不连接到任何mongodb有时很方便,通过--nodb参数启动shell,启动时就不会连接到任何数据库。启动之后,在需要时运行new Mongo(hostname)命令就可以连接到想要的mongodb。比如:>conn = new Mongo("some-host:3000");>db = conn.getDB("myDB");

你可以通过执行以下命令来连接MongoDB的服务。可以通过db.help()查看数据库级别的帮助,使用db.[collectionName].help()查看集合级别的帮助,如果想知道一个函数是做什么用的,可以通过直接在shell输入函数名(不包含小括号),就可以看到相应的JavaScript实现代码。例如:db.runoob.update。

在shell中执行脚本:直接在命令行中传递脚本就可以了,例如:mongo script1.js script2.js script3.js。如果希望使用指定的主机/端口上的mongod运行脚本,需要先指定地址,然后再跟上脚本文件的名称:$ mongo --quiet server-1:3000/foo script1.js  script2.js  script3.js,这样可以将db指向server-1:3000上的foo数据库,然后执行者三个脚本。也可以使用load()函数,从交互式shell中运行脚本,例如:load("script1.js")。

注意:localhost为主机名,这个选项是必须的:

mongodb://localhost

当你执行以上命令时,你可以看到以下输出结果:

$ ./mongo
MongoDB shell version: 3.0.6
connecting to: test
> mongodb://localhostmongodb://localhost
...

这时候你返回查看运行 ./mongod 命令的窗口,可以看到是从哪里连接到MongoDB的服务器,您可以看到如下信息:

……省略信息……
2015-09-25T17:22:27.336+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2015-09-25T17:22:27.336+0800 I CONTROL  [initandlisten] options: { storage: { dbPath: "/data/db" } }
2015-09-25T17:22:27.350+0800 I NETWORK  [initandlisten] waiting for connections on port 27017
2015-09-25T17:22:36.012+0800 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:37310 #1 (1 connection now open)  # 该行表明一个来自本机的连接

……省略信息……

 


MongoDB连接命令格式

使用用户名和密码连接到MongoDB服务器,你必须使用 'username:password@hostname/dbname' 格式,'username'为用户名,'password' 为密码。

使用用户名和密码连接登陆到默认数据库:

$ ./mongo
MongoDB shell version: 3.0.6
connecting to: test
mongodb://admin:123456@localhost/

以上命令中,用户 admin 使用密码 123456 连接到本地的 MongoDB 服务上。输出结果如下所示:<、p>

> mongodb://admin:123456@localhost/
...

使用用户名和密码连接登陆到指定数据库:

连接到指定数据库的格式如下:

mongodb://admin:123456@localhost/test

 


更多连接实例

连接本地数据库服务器,端口是默认的。

mongodb://localhost

使用用户名fred,密码foobar登录localhost的admin数据库。

mongodb://fred:foobar@localhost

使用用户名fred,密码foobar登录localhost的baz数据库。

mongodb://fred:foobar@localhost/baz

连接 replica pair, 服务器1为example1.com服务器2为example2。

mongodb://example1.com:27017,example2.com:27017

连接 replica set 三台服务器 (端口 27017, 27018, 和27019):

mongodb://localhost,localhost:27018,localhost:27019

连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。

mongodb://host1,host2,host3/?slaveOk=true

直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。

mongodb://host1,host2,host3/?connect=direct;slaveOk=true

当你的连接服务器有优先级,还需要列出所有服务器,你可以使用上述连接方式。

安全模式连接到localhost:

mongodb://localhost/?safe=true

以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。

mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000

 


参数选项说明

标准格式:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

标准的连接格式包含了多个选项(options),如下所示:

 

选项描述
replicaSet=name 验证replica set的名称。 Impliesconnect=replicaSet.
slaveOk=true|false
  • true:在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。
  • false: 在 connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet 模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。
safe=true|false
  • true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS).
false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。
w=n 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。
wtimeoutMS=ms 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
fsync=true|false
  • true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true.
  • false: 驱动不会添加到getLastError命令中。
journal=true|false 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
connectTimeoutMS=ms 可以打开连接的时间。
socketTimeoutMS=ms 发送和接受sockets的时间。

另外,需要注意集合的命名规范:通常可以使用db.collectionName获取一个集合的内容,但是,如果集合名称中包含保留字或者无效的js属性名称,db.collectionName就不能正常工作了。比如,要访问version集合,不能直接使用db.version,因为db.version是db的一个方法,为了访问version集合,必须使用getCollection函数,例如db.getCollection("version");还有一种方法可以访问以无效属性名称命名的集合,那就是使用数组访问语法。例如:

var collections=["posts","comments","authors"];for(var i in collections){print(db.blog[collections[i]]);}。还可以使用这样的方式访问名字怪异的集合,>var name="@#$" ;>dfb[name].find()。直接使用db.@#$进行查询是非法的。

 

posted on 2016-12-05 13:57  一日三省吾身  阅读(1004)  评论(0编辑  收藏  举报