不管我们学习什么数据库都应该学习其中的基础概念,在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 对应的术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
数据库服务和客户端 | |
Mysqld/Oracle | mongod |
mysql/sqlplus | mongo |
需要注意的是:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意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为主机名,这个选项是必须的:
当你执行以上命令时,你可以看到以下输出结果:
$ ./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/
...
使用用户名和密码连接登陆到指定数据库:
连接到指定数据库的格式如下:
更多连接实例
连接本地数据库服务器,端口是默认的。
使用用户名fred,密码foobar登录localhost的admin数据库。
使用用户名fred,密码foobar登录localhost的baz数据库。
连接 replica pair, 服务器1为example1.com服务器2为example2。
连接 replica set 三台服务器 (端口 27017, 27018, 和27019):
连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
当你的连接服务器有优先级,还需要列出所有服务器,你可以使用上述连接方式。
安全模式连接到localhost:
以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
参数选项说明
标准格式:
标准的连接格式包含了多个选项(options),如下所示:
选项 | 描述 |
---|---|
replicaSet=name | 验证replica set的名称。 Impliesconnect=replicaSet. |
slaveOk=true|false |
|
safe=true|false |
|
w=n | 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。 |
wtimeoutMS=ms | 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true. |
fsync=true|false |
|
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.@#$进行查询是非法的。