1 下载安装
安装MongoDB非常的简单,仅需下载压缩包解压运行命令即可,
下载地址:http://www.mongodb.org/downloads,本文为windows平台,
MongoDB运行命令:>bin/mongod。
提示:首先要创建存储数据的文件夹,MongoDB 默认存储数据目录为 /data/db/ (或者 c:/data/db),当然你也可以修改成不同目录,只需要指定 --dbpath 参数,eg:
>bin/mongod --dbpath=d:/mgdata/db
2 建库建表
MongoDB创建数据库,MongoDB创建数据库,MongoDB创建数据库,MongoDB创建数据库
MongoDB创建数据库完全可以使用use
如下:
use mydb;
这样就创建了一个数据库。
这一步很重要如果什么都不操作离开的话 这个库就会被系统删除。
验证-------------------------------
然后使用插入语句:
db.usr.insert({'name':'tompig'});
db.usr.insert({'name':'tompig1','id':1});
在使用下列命令查看
show collections; ---查看‘表’
> show collections;
system.indexes
usr
show dbs 查看库。
> show dbs;
local (empty)
test 0.078125GB
查询记录
> db.usr.find();
{ "_id" : ObjectId("4f459f01bb327e6587380b58"), "name" : "lein" }
{ "_id" : ObjectId("4f45a14dbb327e6587380b59"), "name" : "leinchu", "id" : 2 }
>
> db.usr.find();{ "_id" : ObjectId("4f459f01bb327e6587380b58"), "name" : "lein" }{ "_id" : ObjectId("4f45a14dbb327e6587380b59"), "name" : "leinchu", "id" : 2 }> db.usr.insert({'name':'leinchu','id':2});> db.usr.insert({'name':'leinchu1','id':3});> db.usr.find({'id':2});{ "_id" : ObjectId("4f45a14dbb327e6587380b59"), "name" : "leinchu", "id" : 2 }{ "_id" : ObjectId("4f45a870bb327e6587380b5a"), "name" : "leinchu", "id" : 2 }> db.usr.find({'id':'2'});>
打开游览器输入URL “http://localhost:27017/”,如果出现下面的页面则说明已正常启动:
You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number |
http://localhost:28017/

3 优点和特性
使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种BSON作为内部存储的格式和语法。针对MongoDB的操作都使用JSON风格语法,客户端提交或接收的数据都使用JSON形式来展现。相对于SQL来说,更加直观,容易理解和掌握。
Schema-less,支持嵌入子文档:MongoDB是一个Schema-free的文档数据库。一个数据库可以有多个Collection,每个Collection是Documents的集合。Collection和Document和传统数据库的Table和Row并不对等。无需事先定义Collection,随时可以创建。
作品和评论可以设计为一个collection,评论作为子文档内嵌在art的comments属性中,评论的回复则作为comment子文档的子文档内嵌于replies属性。按照这种设计模式,只需要按照作品id检索一次,即可获得所有相关的信息了。在MongoDB中,不强调一定对数据进行Normalize ,很多场合都建议De-normalize,开发人员可以扔掉传统关系数据库各种范式的限制,不需要把所有的实体都映射为一个Collection,只需定义最顶级的class。MongoDB的文档模型可以让我们很轻松就能将自己的Object映射到collection中实现存储。
Collection中可以包含具有不同schema的文档记录。 这意味着,你上一条记录中的文档有3个属性,而下一条记录的文档可以有10个属性,属性的类型既可以是基本的数据类型(如数字、字符串、日期等),也可以是数组或者散列,甚至还可以是一个子文档(embed document)。这样,可以实现逆规范化(denormalizing)的数据模型,提高查询的速度。
CRUD更加简单,支持in-place update:只要定义一个数组,然后传递给MongoDB的insert/update方法就可自动插入或更新;对于更新模式,MongoDB支持一个upsert选项,即:“如果记录存在那么更新,否则插入”。MongoDB的update方法还支持Modifier,通过Modifier可实现在服务端即时更新,省去客户端和服务端的通讯。这些modifer可以让MongoDB具有和Redis、Memcached等KV类似的功能:较之MySQL,MonoDB更加简单快速。Modifier也是MongoDB可以作为对用户行为跟踪的容器。在实际中使用Modifier来将用户的交互行为快速保存到MongoDB中以便后期进行统计分析和个性化定制。
所有的属性类型都支持索引,甚至数组:这可以让某些任务实现起来非常的轻松。在MongoDB中,“_id”属性是主键,默认MongoDB会对_id创建一个唯一索引。
服务端脚本和Map/Reduce:MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。MongoDB不支持事务级别的锁定,对于某些需要自定义的“原子性”操作,可以使用Server side脚本来实现,此时整个MongoDB处于锁定状态。Map/Reduce也是MongoDB中比较吸引人的特性。Map/Reduce可以对大数据量的表进行统计、分类、合并的工作,完成原先SQL的GroupBy等聚合函数的功能。并且Mapper和Reducer的定义都是用Javascript来定义服务端脚本。
性能高效,速度快: MongoDB使用c++/boost编写,在多数场合,其查询速度对比MySQL要快的多,对于CPU占用非常小。部署也很简单,对大多数系统,只需下载后二进制包解压就可以直接运行,几乎是零配置。
支持多种复制模式: MongoDB支持不同的服务器间进行复制,包括双机互备的容错方案。
Master-Slave是最常见的。通过Master-Slave可以实现数据的备份。在我们的实践中,我们使用的是Master-Slave模式,Slave只用于后备,实际的读写都是从Master节点执行。
Replica Pairs/Replica Sets允许2个MongoDB相互监听,实现双机互备的容错。
MongoDB只能支持有限的双主模式(Master-Master),实际可用性不强,可忽略
内置GridFS,支持大容量的存储:这个特点是最吸引我眼球的,也是让我放弃其他NoSQL的一个原因。GridFS具体实现其实很简单,本质仍然是将文件分块后存储到files.file和files.chunk 2个collection中,在各个主流的driver实现中,都封装了对于GridFS的操作。由于GridFS自身也是一个Collection,你可以直接对文件的属性进行定义和管理,通过这些属性就可以快速找到所需要的文件,轻松管理海量的文件,无需费神如何hash才能避免文件系统检索性能问题, 结合下面的Auto-sharding,GridFS的扩展能力是足够我们使用了。在实践中,我们用MongoDB的GridFs存储图片和各种尺寸的缩略图。
内置Sharding,提供基于Range的Auto Sharding机制:一个collection可按照记录的范围,分成若干个段,切分到不同的Shard上。Shards可以和复制结合,配合Replica sets能够实现Sharding+fail-over,不同的Shard之间可以负载均衡。查询是对客户端是透明的。客户端执行查询,统计,MapReduce等操作,这些会被MongoDB自动路由到后端的数据节点。这让我们关注于自己的业务,适当的时候可以无痛的升级。MongoDB的Sharding设计能力最大可支持约20petabytes,足以支撑一般应用。
第三方支持丰富: MongoDB社区非常活跃,很多开发框架都迅速提供了对MongDB的支持。不少知名大公司和网站也在生产环境中使用MongoDB,越来越多的创新型企业转而使用MongoDB作为和Django,RoR来搭配的技术方案。
实施MonoDB的过程是令人愉快的。我们对自己的PHP开发框架进行了修改以适应MongoDB。在PHP中,对MongoDB的查询、更新都是围绕Array进行的,实现代码变得很简洁。由于无需建表,MonoDB运行测试单元所需要的时间大大缩短,对于TDD敏捷开发的效率也提高了。当然,由于MongoDB的文档模型和关系数据库有很大不同,在实践中也有很多的困惑,幸运的是,MongoDB开源社区给了我们很大帮助。最终,我们使用了2周就完成了从MySQL到MongoDB的代码移植比预期的开发时间大大缩短。从我们的测试结果看也是非常惊人,数据量约2千万,数据库300G的情况下,读写2000rps,CPU等系统消耗是相当的低(我们的数据量还偏小,目前陆续有些公司也展示了他们的经典案例:MongoDB存储的数据量已超过50亿,>1.5TB)。目前,我们将MongoDB和其他服务共同部署在一起,大大节约了资源。
一些小提示
切实领会MongoDB的Document模型,从实际出发,扔掉关系数据库的范式思维定义,重新设计类;在服务端运行的JavaScript代码避免使用遍历记录这种耗时的操作,相反要用Map/Reduce来完成这种表数据的处理;属性的类型插入和查询时应该保持一致。若插入时是字符串“1”,则查询时用数字1是不匹配的;优化MongoDB的性能可以从磁盘速度和内存着手;MongoDB对每个Document的限制是最大不超过4MB;在符合上述条件下多启用EmbedDocument, 避免使用DatabaseReference;内部缓存可以避免N+1次查询问题(MongoDB不支持joins)。
用Capped Collection解决需要高速写入的场合,如实时日志;大数据量情况下,新建同步时要调高oplogSize的大小,并且自己预先生成数据文件,避免出现客户端超时;Collection+Index合计数量默认不能超过24000;当前版本( use foo
switched to db foo
> db.addUser("user1","pwd1")
{
"user" : "user1",
"readOnly" : false,
"pwd" : "35263c100eea1512cf3c3ed83789d5e4"
}[/td][/tr][/table] 在admin中创建用户名为root密码为pwd2的用户,如下:
> use admin
switched to db admin
> db.addUser("root", "pwd2")
{
"_id" : ObjectId("4f8a87bce495a88dad4613ad"),
"user" : "root",
"readOnly" : false,
"pwd" : "20919e9a557a9687c8016e314f07df42"
}
> db.auth("root", "pwd2")
1
> |
在admin库建立的用户对所有库有权限,而在指定库的就只能在指定库有权限
(1)、mongoexport导出工具
MongoDB提供了mongoexport工具,可以把一个collection导出成json格式或csv格式的文件。可以指定导出哪些数据项,也可以根据给定的条件导出数据。工具帮助信息如下:
[iyunv@localhost bin]# ./mongoexport --help
options:
--help produce help message
-v [ --verbose ] be more verbose (include multiple times for more
verbosity e.g. -vvvvv)
-h [ --host ] arg mongo host to connect to ( /s1,s2 for sets)
--port arg server port. Can also use --host hostname:port
--ipv6 enable IPv6 support (disabled by default)
-u [ --username ] arg username
-p [ --password ] arg password
--dbpath arg directly access mongod database files in the given
path, instead of connecting to a mongod server -
needs to lock the data directory, so cannot be used
if a mongod is currently accessing the same path
--directoryperdb if dbpath specified, each db is in a separate
directory
-d [ --db ] arg database to use
-c [ --collection ] arg collection to use (some commands)
-f [ --fields ] arg comma separated list of field names e.g. -f name,age
--fieldFile arg file with fields names - 1 per line
-q [ --query ] arg query filter, as a JSON string
--csv export to csv instead of json
-o [ --out ] arg output file; if not specified, stdout is used
--jsonArray output to a json array rather than one object per
line
[iyunv@localhost bin]# |
下面我们将以一个实际的例子说明,此工具的用法:
将foo库中的表t1导出成json格式:
[iyunv@localhost bin]# ./mongoexport -d foo -c t1 -o /data/t1.json
connected to: 127.0.0.1
exported 1 records
[iyunv@localhost bin]# |
导出成功后我们看一下/data/t1.json文件的样式,是否是我们所希望的:
[iyunv@localhost data]# more t1.json
{ "_id" : { "$oid" : "4f927e2385b7a6814a0540a0" }, "age" : 2 }
[iyunv@localhost data]# |
通过以上说明导出成功,但有一个问题,要是异构数据库的迁移怎么办呢?例如我们要将MongoDB的数据导入到MySQL该怎么办呢?MongoDB提供了一种csv的导出格式,就可以解决异构数据库迁移的问题了. 下面将foo库的t2表的age和name列导出, 具体如下:
[iyunv@localhost bin]# ./mongoexport -d foo -c t2 --csv -f age,name -o /data/t2.csv
connected to: 127.0.0.1
exported 1 records
[iyunv@localhost bin]# |
查看/data/t2.csv的导出结果:
[iyunv@localhost data]# more t2.csv
age,name
1,"wwl"
[iyunv@localhost data]# |
可以看出MongoDB为我们提供了一个强在的数据导出工具。
(2)、mongoimport导入工具
MongoDB提供了mongoimport工具,可以把一个特定格式文件中的内容导入到某张collection中。工具帮助信息如下:
[iyunv@localhost bin]# ./mongoimport --help
options:
--help produce help message
-v [ --verbose ] be more verbose (include multiple times for more
verbosity e.g. -vvvvv)
-h [ --host ] arg mongo host to connect to ( /s1,s2 for sets)
--port arg server port. Can also use --host hostname:port
--ipv6 enable IPv6 support (disabled by default)
-u [ --username ] arg username
-p [ --password ] arg password
--dbpath arg directly access mongod database files in the given
path, instead of connecting to a mongod server -
needs to lock the data directory, so cannot be used
if a mongod is currently accessing the same path
--directoryperdb if dbpath specified, each db is in a separate
directory
-d [ --db ] arg database to use
-c [ --collection ] arg collection to use (some commands)
-f [ --fields ] arg comma separated list of field names e.g. -f name,age
--fieldFile arg file with fields names - 1 per line
--ignoreBlanks if given, empty fields in csv and tsv will be ignored
--type arg type of file to import. default: json (json,csv,tsv)
--file arg file to import from; if not specified stdin is used
--drop drop collection first
--headerline CSV,TSV only - use first line as headers
--upsert insert or update objects that already exist
--upsertFields arg comma-separated fields for the query part of the
upsert. You should make sure this is indexed
--stopOnError stop importing at first error rather than continuing
--jsonArray load a json array, not one item per line. Currently
limited to 4MB. |
下面我们将以一人实际的例子说明,此工具的用法:
先看一下foo库中的t1表数据:
> db.t1.find();
{ "_id" : ObjectId("4f937a56450beadc560feaa9"), "age" : 5 }
> |
t1其中有一条age=5的记录, 我们再看一下json文件中的数据是什么样子的:
[iyunv@localhost data]# more t1.json
{ "_id" : { "$oid" : "4f937a56450beadc560feaa7" }, "age" : 8 }
[iyunv@localhost data]# |
可以看到t1.json文件中有一条age=8的数据,下面我们将用mongoimport工具将json文件中的记录导入到t1表中:
[iyunv@localhost bin]# ./mongoimport -d foo -c t1 /data/t1.json
connected to: 127.0.0.1
imported 1 objects | 工具返回信息说明向表中插入了一条记录. 我们进库里实际验证一下:
[iyunv@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use foo
switched to db foo
> db.t1.find();
{ "_id" : ObjectId("4f937a56450beadc560feaa9"), "age" : 5 }
{ "_id" : ObjectId("4f937a56450beadc560feaa7"), "age" : 8 }
> | 结果跟我们期待的是一样的,数据成功插入到表中。
MongoDB备份和恢复
MongoDB提供了两个命令来备份(mongodump )和恢复(mongorestore )数据库。
|