[size=medium]一、简介。[/size]
MongoDB是一个基于分布式文件存储的数据库开源项目。由C++语言编写。旨在为WEB应用提供可护展的高性能数据存储解决方案。
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
*面向集合存储,易存储对象类型的数据。
*模式自由。
*支持动态查询。
*支持完全索引,包含内部对象。
*支持查询。
*支持复制和故障恢复。
*使用高效的二进制数据存储,包括大型对象(如视频等)。
*自动处理碎片,以支持云计算层次的扩展性
*支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
*文件存储格式为BSON(一种JSON的扩展)
*可通过网络访问
所谓“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各中复杂的文件类型。我们称这种存储形式为BSON(Binary Serialized dOcument Format)。
[size=medium]二、安装,启动服务[/size]
MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB
在32位模式运行时支持的最大文件尺寸为2GB。
MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。
安装:
Linux/OS X下:
1 建立数据目录
mkdir -p /data/db
2 下载压缩包
curl -O http://downloads.mongodb.org/linux/mongodb-linux-i686-latest.tgz
3 解压缩文件
tar xzf mongodb-linux-i386-latest.tgz
4 启动服务
bin/mongod run &
5 使用自带客户端连接
/bin/mongo
6 测试
db.foo.save( { a : 1 } )
db.foo.findOne()
windows下:
1 建立数据目录c:\data\db
2 下载压缩包,解压文件
3 启动服务
bin\mongod.exe run
4 自带客户端
bin\mongon.exe
在LINUX和WINDOWS系统下的使用大同小异,不同的地方主要是默认的数据存储目录。LINUX类系统下存放在/data/db下,而WINDOWS
会存放在C:\data\db下。可以在启动时使用--dbpath参数指定存储目录并启动。如:bin\mongod.exe --dbpath d:\data\mongo
常用启动参数:
run 直接启动。例:./mongod run
--dbpath 指定特定存储目录启动,若目录不存在则创建。例:./mongod --dbpath /var/data/mongo
--port 指定端口启动。例:./mongod --port 12345
停止MONGO服务:
方法1:服务端停止,可使用Ctrl+C
方法2:在客户端停止,可先连接客户端
./mongo
并使用命令
db.shutdownerver()
然后退出客户端
exit
[size=medium]三、命令行简介[/size]
mongo 是 MongoDB 自带的交互式 Javascript shell,用来对 Mongod 进行操作和管理的交互式环境。
使用 "./mongo --help" 可查看相关连接参数。
$ ./mongo --help
MongoDB shell version: 1.5.3
usage: ./mongo [options] [db address] [file names (ending in .js)]
db address can be:
foo foo database on local machine
192.169.0.5/foo foo database on 192.168.0.5 machine
192.169.0.5:9999/foo foo database on 192.168.0.5 machine on port 9999
options:
--shell run the shell after executing files
--nodb don't connect to mongod on startup - no 'db address'
arg expected
--quiet be less chatty
--port arg port to connect to
--host arg server to connect to
--eval arg evaluate javascript
-u [ --username ] arg username for authentication
-p [ --password ] arg password for authentication
-h [ --help ] show this usage information
--version show version information
--ipv6 enable IPv6 support (disabled by default)
file names: a list of files to run. files have to end in .js and will exit after unless --shell is specified
相关命令很多,要习惯使用 "help"。
$ ./mongo
MongoDB shell version: 1.5.3
connecting to: test
type "help" for help
> help
help admin misc shell commands
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
use set current database to
db.help() help on DB methods
db.foo.help() help on collection methods
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
exit quit the mongo shell
(1) MongoDB 会自动创建数据库(db)和集合(collection),无需显式执行。
$ ./mongo
MongoDB shell version: 1.5.3
connecting to: test
type "help" for help
> show dbs // 查看当前数据库列表
admin
local
> use blog // 切换到工作数据库
switched to db blog
> db // 当前数据库
blog
> for (var i = 0; i < 10; i++) db.users.save({name : "user" + i, age : i}) // 插入数据
> show dbs // 数据库 blog 被创建
admin
blog
local
> show collections // 列表 users 被创建
system.indexes
users
> db.copyDatabase("blog", "blog2") // 复制数据库,注意:数据库名称要用引号括起来
{ "ok" : true }
> db.copyDatabase("blog", "blog", "192.168.1.202") // 复制到其他机器的数据库,参见四、多台服务器之间复制数据库
> show dbs // 数据库 blog2 被创建
admin
blog
blog2
local
> use blog2 // 切换到 blog2
switched to db blog2
> show collections // 查看集合列表
system.indexes
users
> db.users.find() // 查看被复制的数据
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981a"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981b"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981c"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981d"), "name" : "user3", "age" : 3 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981e"), "name" : "user4", "age" : 4 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac2981f"), "name" : "user5", "age" : 5 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac29820"), "name" : "user6", "age" : 6 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac29821"), "name" : "user7", "age" : 7 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac29822"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4c33f8fcecf2b9320ac29823"), "name" : "user9", "age" : 9 }
> db.dropDatabase() // 删除数据库 blog2
{ "dropped" : "blog2", "ok" : true }
> show dbs // 确认数据库删除成功
admin
blog
local
> use blog // 切换回 blog
switched to db blog
> db.users.drop() // 删除集合 users
true
> show collections // 确认集合被删除
system.indexes
> exit
bye
[size=medium]四、多台服务器之间复制数据库。[/size]
server64$ ./mongo
MongoDB shell version: 1.5.3
connecting to: test
type "help" for help
> use blog
switched to db blog
> for (var i = 0; i < 10; i++) db.users.save({name : "user" + i, age : i})
> use news
switched to db news
> for (var i = 0; i < 10; i++) db.articles.save({title : "title" + i})
> show dbs
admin
blog
local
news
> exit
bye
准备好源数据库后,我们开始在复制。
server32:$ ./mongo
MongoDB shell version: 1.5.4
connecting to: test
> db.copyDatabase("blog", "blog", "192.168.1.202") // 从源服务器复制 blog 数据库
{ "ok" : true }
> show dbs // 复制成功
admin
blog
local
> use blog
switched to db blog
> show collections
system.indexes
users
> db.users.find()
{ "_id" : ObjectId("4c33fadb15b7f104d297e644"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e645"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e646"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e647"), "name" : "user3", "age" : 3 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e648"), "name" : "user4", "age" : 4 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e649"), "name" : "user5", "age" : 5 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64a"), "name" : "user6", "age" : 6 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64b"), "name" : "user7", "age" : 7 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64c"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64d"), "name" : "user9", "age" : 9 }
> use news
switched to db news
> db.cloneDatabase("192.168.1.202") // 从源服务器克隆当前数据库(news)
{ "ok" : true }
> show dbs
admin
blog
local
news
> show collections
articles
system.indexes
> db.articles.find()
{ "_id" : ObjectId("4c33fb6215b7f104d297e64e"), "title" : "title0" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e64f"), "title" : "title1" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e650"), "title" : "title2" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e651"), "title" : "title3" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e652"), "title" : "title4" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e653"), "title" : "title5" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e654"), "title" : "title6" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e655"), "title" : "title7" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e656"), "title" : "title8" }
{ "_id" : ObjectId("4c33fb6215b7f104d297e657"), "title" : "title9" }
> exit
bye
(3) 当我们使用 use 切换到某个数据库时,变量 db 表示当前数据库。还可以用 getSisterDB() 函数获取其他数据库的引用。
> use admin
switched to db admin
> db
admin
> blog = db.getSisterDB("blog")
blog
> blog.users.insert({name : "abc"})
> blog.users.find({name : "abc"})
{ "_id" : ObjectId("4c3419b0492aa4cfbec11895"), "name" : "abc" }
(4) 调用 fsync 命令,可以强制将内存中缓存数据写回数据库文件。如果不想等待,可添加 async 参数异步执行。
> use admin
switched to db admin
> db.runCommand({fsync : 1})
{ "numFiles" : 6, "ok" : true }
> db.runCommand({fsync : 1, async : true})
{ "numFiles" : 6, "ok" : true }
(5) 某些时候需要锁定系统,阻塞所有写操作,诸如备份、整理数据库等等。锁定时读操作不受影响。
$ ./mongo
MongoDB shell version: 1.5.3
connecting to: test
type "help" for help
> use blog
switched to db blog
> admin = db.getSisterDB("admin")
admin
> admin.runCommand({fsync : 1, lock : 1}) // 锁定
{
"info" : "now locked against writes, use db.$cmd.sys.unlock.findOne() to unlock",
"ok" : true
}
> db.users.find() // 读操作正常
{ "_id" : ObjectId("4c33fadb15b7f104d297e644"), "name" : "user0", "age" : 0 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e645"), "name" : "user1", "age" : 1 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e646"), "name" : "user2", "age" : 2 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e647"), "name" : "user3", "age" : 3 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e648"), "name" : "user4", "age" : 4 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e649"), "name" : "user5", "age" : 5 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64a"), "name" : "user6", "age" : 6 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64b"), "name" : "user7", "age" : 7 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64c"), "name" : "user8", "age" : 8 }
{ "_id" : ObjectId("4c33fadb15b7f104d297e64d"), "name" : "user9", "age" : 9 }
> db.users.save({name : "xyz" }) // 写操作被阻塞,等待 ...
另开启一个终端,解除锁定。
> use admin
switched to db admin
> db.$cmd.sys.unlock.findOne()
{ "ok" : 1, "info" : "unlock requested" }
解除后,前一终端被阻塞的写操作正确返回。
(6) 调用 validate() 验证集合是否存在错误。
> db.users.validate()
{
"ns" : "blog.users",
"result" : "
validate
firstExtent:0:2600 ns:blog.users
lastExtent:0:23d00 ns:blog.users
# extents:2
datasize?:4640 nrecords?:116 lastExtentSize:9216
padding:1
first extent:
loc:0:2600 xnext:0:23d00 xprev:null
nsdiag:blog.users
size:2304 firstRecord:0:26b0 lastRecord:0:2ec8
116 objects found, nobj:116
6496 bytes data w/headers
4640 bytes data wout/headers
deletedList: 0000000010000000000
deleted: n: 1 size: 4672
nIndexes:1
blog.users.$_id_ keys:116
",
"ok" : true,
"valid" : true,
"lastExtentSize" : 9216
}