最近有些时间,就抽空研究了一下MongoDB,我之前常用关系型数据库,如Oracle、MySQL,对MongoDB只是有些很肤浅的了解,最近下决心要好好研究一下,主要的参考书有两本:《MongoDB 大数据处理权威指南(第二版)》、《MongoDB权威指南(初版)》,后者的版本比较旧,但基本还能够用,基本的操做方式基本上差很少。我主要参考的是第一个本书,相对来讲,第一本书比较简单,但入门比较容易,还带有PHP和Python的操做MongoDB的指南。javascript
一、安装:MongoDB的安装比较简单,主站是www.mongodb.org,既有32位的版本,也有64位的版本,尽可能使用64位的版本。java
Windows环境下,能够下载对应的安装包,安装便可linux
Linux能够下载压缩包,若是使用Ubuntu或者Fedora的话,还能够经过在线档案库下载安装,这样能够安装到最新版本,具体安装内容能够参考https://docs.mongodb.org/manual/administration/install-on-linux/,这是mongoDB的官方文档,若是有什么问题,能够到这里查看一下,比较权威,内容也比较全。sql
我安装和测试的环境以下mongodb
Windows 10 专业版shell
MongoDB 3.0.6版,安装路径为D:\Program Files\MongoDB数据库
为方便使用mongoDB,将其命令目录加入到环境变量Path里,默认命令保存在D:\Program Files\MongoDB\Server\3.0\bin编程
二、MongoDB相对于Oracle、Mysql来讲,结构上要简单不少,同Oracle同样,其一个实例能够有多个数据库,数据库里面能够任意多个Collection,Collection相似于Oracle中的表概念,可是有本质的不容,Collection中的每一行保存的是键值对,叫Document,这也是mongoDB叫面向文档的数据的一个缘由,若是对Json熟悉,理解这个也很是快,键很容易理解,能够理解为表中的列名,可是其值就比较特别了,能够是数组,也能够是键值对,而且Collection中的键很是自由,其下的Documnet能够拥有不一样的键,简单来讲,Documnet虽然属于一个Collection,可是其键值对是没有限制的,想怎么样,就怎么样。这种存储方式,既有其优点,也有其劣势。数组
优点:(相对关系型数据库来讲)性能
1)因为存储方式简单,CUID的速度是很是快的,有这么一句话:mongoDB若是查询超过了1秒钟,必然是出了问题
2)同一Collection下的Document之间没什么硬性约束,不一样的Collection之间也没有什么约束,因此没有关系型数据库的完整性要求,这一点对于复制、分片是很是重要的。
3)复制、分片相对关系型数据库来讲,要容易的多,能够经过横向扩展来提高系统性能。
劣势:(相对于关系型数据库来讲)
1)因为没有完整性约束,因此数据的规范性较为困难,须要良好的编程纪律和查错手段来约束
2)缺少对事务的支持,不适合应用到财务系统
3)缺少Collection联查功能(也许未来会有),不少关系型数据库须要的操做会很不方便,生成报表须要使用MapReduce才能够。
总之,MongoDB的性能、扩展、复制、分片有独特的优点,因此其不太适合于企业应用程序开发,可是很是适合互联网、云计算相关应用的开发,因此须要选择适合的范围用好它。
三、简单操做
1)启动
从命令行启动mongoDB的命令是mongod,须要指定端口和数据库数据路径,在本机创建了数据库目录d:\mongodb_data\db1,端口为27017
mongod --dbpath d:\mongodb_data\db1 --port 27017
2)链接
mongodDB提供了一个命令行接口mongo,这是一个Javascript的终端,能够经过javascript脚原本操做数据库
D:\>mongo 192.168.1.223:27017
MongoDB shell version: 3.0.6
connecting to: 192.168.1.223:27017/test
>
(192.168.1.223为本机ip,若是链接远程mongoDB,须要修改IP地址)
3)选择数据库
默认是链接到test数据库,咱们建立一个新数据库,如shiyq,以下
> use shiyq
(须要注意,use是切换数据库的命令,若是没有这个数据库,系统会默认建立一个,并且数据库名是区分大小写的,因此用这个命令要细心一点)
> use shiyq
switched to db shiyq
> db
shiyq
> show dbs
local 0.078GB
test 0.078GB
testdb 0.078GB
> show collections;
>
能够看出db命令是显示当前数据库,show dbs是显示本实例中有哪些数据库,由于shiyq是新数据库,没有内容,因此没有显示出来,show collections显示本数据库中的Collection名称,目前尚未,因此没有显示。
4)建立Document
> db.students.insert({name:'王强',code:'s101-1',age:15});
WriteResult({ "nInserted" : 1 })
> db.students.insert({name:'刘欢',code:'s101-2',age:18});
WriteResult({ "nInserted" : 1 })
> db.students.insert({name:'赵成',code:'s101-3',age:17});
WriteResult({ "nInserted" : 1 })
> db.students.insert({name:'赵成',code:'s101-4',age:19});
WriteResult({ "nInserted" : 1 })
> db.students.insert({name:'赵成',code:'s101-5',age:19});
WriteResult({ "nInserted" : 1 })
collection名称是students,能够看到collection是不须要建立的,只要建立其下的document就能够了;
> db.students.find()
{ "_id" : ObjectId("560b95bd3bd6389af11ee3d0"), "name" : "王强", "code" : "s101-1", "age" : 15 }
{ "_id" : ObjectId("560b961c3bd6389af11ee3d1"), "name" : "刘欢", "code" : "s101-2", "age" : 18 }
{ "_id" : ObjectId("560b96353bd6389af11ee3d2"), "name" : "赵成", "code" : "s101-3", "age" : 17 }
{ "_id" : ObjectId("560b963c3bd6389af11ee3d3"), "name" : "赵成", "code" : "s101-4", "age" : 19 }
{ "_id" : ObjectId("560b96413bd6389af11ee3d4"), "name" : "赵成", "code" : "s101-5", "age" : 19 }
能够看出已经插入的数据,须要注意每个Document都有一个_id字段,这个至关于Collection的主键,这个键值也能够手工指定,若是是系统指定,能够保证在复制、分片中没有冲突。
若是使用NodeJS,或者对Javascript比较熟悉,上面的内容也很是容易理解。
5)更新
语法:db.collection.update(criteria,objNew,options)
criteria是过滤条件,objNew是新的内容,options={upsert:true,multi:true},upsert=true,若是存在更新,不然建立,multi=true,若是多条数据符合,则所有更新,默认只更新第一条(须要注意,若是不指定键,没法使用multi=true),须要注意的是这里的objNew会彻底替代原始内容,若是要修改单个键值,不能用这个方法。
> db.students.update({name:'王强'},{grade:1});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.students.find() );
{ "_id" : ObjectId("560b95bd3bd6389af11ee3d0"), "grade" : 1 }
6)删除:
> db.students.remove({grade:1});
WriteResult({ "nRemoved" : 1 })
其余的操做还有不少,好比
db.collection.save(),有_id更新,没有则新增
$inc 增长值
$set 修改单个键值
$unset 删除键值
$push 向数组键中增长值
$pull 从数组键中删除全部值
$pullAll 从数组中删除多个值
$pop 删除数组中最后一个值
上述$的同一语法为db.collection.update(criteria,{$set:{Author:'shiyq'});