MongoDB数据库一(MongoDB数据库管理)_第1页
MongoDB数据库一(MongoDB数据库管理)_第2页
MongoDB数据库一(MongoDB数据库管理)_第3页
MongoDB数据库一(MongoDB数据库管理)_第4页
MongoDB数据库一(MongoDB数据库管理)_第5页
已阅读5页,还剩122页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MongoDB数据库管理主讲:李捷QQ:86267659个人主页:www.li-jie.me邮箱:lijie@单元目标1.什么是NO-SQL?2.认识MongoDB数据库3.MongoDB的下载与安装4.MongoDB的体系结构5.客户端GUI工具集合6.常用命令(基本的增删改查)什么是NO-SQLNoSQL是反SQL运动的意思,它指的是非关系型的数据库,是以key-value形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求,比如说遵循SQL标准、ACID属性、表结构等等,这类数据库主要有以下特点:非关系型的、分布式的、开源的、水平可扩展的。NoSQL发展现状目前国内外正在应用NoSQL的网站有:新浪微博 RedisGoogle

BigtableAmazon

SimpleDB淘宝数据平台 Tair

(淘宝自主开发的Key/Value结构数据存储系统)视觉中国网站 MongoDB

优酷运营数据分析 MongoDB飞信空间 HandlerSocket豆瓣社区 BeansDB

我们为什么要使用NOSQL非关系数据库?一、对数据库高并发读写的需求二、对海量数据的高效率存储和访问的需求三、和高可用性的需求对数据库的高可扩展性NoSQL数据库的优缺点在优势方面,主要体现在下面这几点:简单的扩展快速的读写低廉的成本灵活的数据模型在不足方面,常见主要有下面这几点:不提供对SQL的支持支持的特性不够丰富现有产品的不够成熟NOSQL的种类初始MongoDBMongoDB介绍MongoDB是什么?{“name”:”mongo”,”type”:”DB”}MongoDB(from“humongous”)Isascalable,high-performance,opensource,Document-orienteddatabase,WritteninC++是一个可扩展,高性能,开放源码,面向文档的数据库,使用C++编写的浅谈原理内存映射存储引擎MongoDB数据库MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能、易部署、易使用,存储数据非常方便。

MongoDB数据库主要功能特性:◆面向集合存储,易存储对象类型的数据“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。◆模式自由模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。◆支持动态查询◆支持完全索引,包含内部对象

MongoDB数据库◆支持查询◆支持复制和故障恢复◆使用高效的二进制数据存储,包括大型对象(如视频等)◆自动处理碎片,以支持云计算层次的扩展性◆支持RUBY,PYTHON,JAVA,C++,PHP等多种语言◆文件存储格式为BSON(一种JSON的扩展)BSON(BinarySerializedDocumentFormat)存储形式是指:存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各中复杂的文件类型。MongoDB数据库◆可通过网络访问

MongoDB服务端可运行在Linux、Windows或OSX平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。

MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。MongoDB数据库面向集合(Collenction-Orented)意思是数据被分组存储在数据集中被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库里的表,不同的是它不需要定义任何模式。MongoDB数据库模式自由(schema-free)

意思是集合里面没有列和行的概念,下面两个记录可以存在于同一个集合里面:

{“name":“mongo"}

{"age":25}MongoDB数据库文档型(documents)意思是我们存储的数据是键-值对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档,每一个文档相当于关系数据库中的一条记录。MongoDB介绍文档是什么?这个Document,不是文件!!{“name”:”李捷”,”alias”:”李小帅”}NotJSON,BUTBSONMongoDB的体系结构1、逻辑结构关系对比关系型数据库:MySQL数据库(database)、表(table)、记录(rows)三个层次概念组成。非关系型数据库: MongoDB数据库(database)、集合(collection)、文档对象(document)三个层次概念组成。MongoDB里的集合对应于关系型数据库里的表,但是集合中没有列、行和关系的概念,集合中只有文档,一个文档就相当与一条记录,这体现了模式自由的特点。2、数据存储结构MySQL的数据存储结构: MySQL的每个数据库存放在一个与数据库同名的文件夹中,MySQL如果使用MyISAM存储引擎,数据库文件类型就包括.frm、.MYD、.MYI。MongoDB的数据存储结构: MongoDB的默认数据目录是/data/db,它负责存储所有的MongoDB的数据文件。在MongoDB内部,每个数据库都包含一个.ns文件和一些数据文件,而且这些数据文件会随着数据量的增加而变得越来越多。所以如果系统中有一个叫做test的数库,那么构成test这个数据库的文件就会由test.ns,test.0,test.1等等组成。3、MongoDB数据类型

MongoDB的文档使用BSON(BinaryJSON)来组织数据,BSON类似于JSON,JSON只是一种简单的表示数据的方式,只包含了6种数据类型(null、布尔、数字、字符串、数组及对象),不能完全满足复杂业务的需要,因此,BSON还提供日期、32位数字、64位数字等类型。以下对mongoDB的数据类型进行简要说明:

1、

nullnull类型用于表示空值或不存在的字段如:{“one”:null}2、

布尔类型

布尔类型有两上值,’true’和’false’

如:{“one”:true}3、

32位整数

mongoDB的控制台使用JS引擎进行输入,而JS仅支持64位浮点数,所以32位整数将会被自动转义。4、

64位整数

64位整数与32位整数一样,在MongoDB控制台使用时,会转义成64位浮点数。5、

64位浮点数

MongoDB控制台数字的默认类型。如:{“one”:2.02}

{“one”:10}6、字符串

UTF-8字符串都可以表示为字符串类型的数据。如:{“one”:”HelloWorld”}7、

符号

在MongoDB控制台中不支持这种类型,将自动转义成字符串。8、

ObjectId类型对象id是文档中唯一的12位的ID

0|1|2|3|4|5|6|7|8|9|10|11时间戳

|机器

|PID|

计数器

如:ObjectId("4eae239f63520362e051e7fd")9、

日期注意:使用的时候要加上new如:{“one”:newDate()}

10、正则表达式

文档键值可以包含正则表达式,其正则表达式采用JS语法来表示。如:{“one”:/ho/i}11、代码

文档中可以包含JS代码

如:{“one”:function(){/*………….*/}}12、数组

文档中键值可以表示为数组,在数组内还可以嵌套数组;如:{“x”:[“a”,”b”,[“c”,”d”]]}13、内嵌文档

文档可以包含别的文档,也可以作为值嵌入到父文档中。如:{“x”:{“name”:”Tom”,”age”:20}}MongoDB的安装(Linux平台)第一步:下载MongoDB安装包MongoDB的官网:

找到相应的版本下载。如果有网络的话,用命令直接下载(CentOS版本)wget/linux/mongodb-linux-i686-1.8.0.tgzMongoDB的安装(Linux平台)第二步:解压压缩包tarzxvfmongodb-linux-i686-2.0.2.tgz最好给解压的文件夹改个名字,方便操作。mvmongodb-linux-i686-2.0.2mongodbMongoDB的安装(Linux平台)第三步:安装准备将mongodb移动到/usr/local/mongdb文件夹(跟据个人习惯指定) mvmongodb/usr/local/mongodb创建数据库文件夹(默认的数据库文件的位置是/data/db,启动时会自动创建) mkdir/usr/local/mongodb/data提示:mongoDB没有具体的安装过程,解压文件包后,可以直接使用,非常高效和方便。MongoDB的安装(Linux平台)第四步:开机自启动将mongodb启动项目加入rc.local保证mongodb在服务器开机时启动

echo"/usr/local/mongodb/bin/mongod--dbpath=/usr/local/mongodb/data">>/etc/rc.localMongoDB的安装(Linux平台)第五步:启动mongodb运行mongod命令--dbpath执行数据库存放路径(默认是/data/db)--fork是以Daemon(守护进程)方式运行,

注意:如果指定--fork参数,必须指定--logpath 日志文件路径/usr/local/mongodb/bin/mongod--dbpath=/usr/local/mongodb/data--fork --logpath=/usr/local/mongodb/dblogs不加--fork参数启动成功加--fork参数启动成功

注意:如果不加--fork参数,则需要再开启一个MongoDB启动窗口。

启动命令常用参数选项说明

--dbpath指定数据库的目录--port指定数据库的端口,默认是27017--bind_ip绑定IP--directoryperdb为每个db创建一个独立子目录--logpath指定日志存放目录--logappend指定日志生成方式(追加/覆盖)--pidfilepath指定进程文件路径,如果不指定,将不产生进程文件--keyFile集群模式的关键标识--journal启用日志--nssize指定.ns文件的大小,单位MB,默认是16M,最大是2GB--maxConns最大的并发连接数--notablescan不允许进行表扫描--noprealloc关闭数据文件的预分配功能--fork以后台Daemon形式运行服务更多的参数选项利用mongod--help进行查看MongoDB的安装(Linux平台)第六步:进入客户端操作/usr/local/mongodb/bin/mongo(mongo命令)看到这个画面:已经进入MongoDB的客户端了,MongoDB的安装也就完成了,就是这么简单。(默认进入的是test库)

MongoDB的安装(Linux平台)第七步:退出shell控制台Ctrl+c或exit回车如图:第八步:停止MongoDB服务器如果处理连接状态,那么直接可以通过在admin库中发送db.shutdownServer()指令去停止具体如下:MongoDB的安装(Linux平台)Unix系统指令注意:

不要用kill-9PID来杀死MongoDB进程,这样可以会导致MongoDB的数据损坏,用kill-2杀死进程。MongoDB的安装(Linux平台)客户端GUI工具集合 MongoDB常用的几款GUI管理工具:MongoVUE主页:/

一个桌面程序,提供了对MongoDB数据库的基,如查看、查询、更新、删除等,简单易用,但是功能还比较弱,以后发展应该不错。RockMongo主页:/p/rock-php

RockMongo是一个PHP5写的MongoDB管理工具。主要特征:使用宽松的NewBSDLicense协议速度快,安装简单。支持多语言(目前提供中文、英文、日文、巴西葡萄牙语、法语、德语)系统可以配置多个主机,每个主机可以有多个管理员,需要管理员密码才能登入操作,确保数据库的安全性。

MongoHub 主页:/bububa/MongoHub

MongoHub是一个针对Mac平台的MongoDB图形管理客户端,可用来管理MongoDB数据的应用程序。常用命令控制台中的基本操作命令

如果想查看当前连接在哪个数据库下面,可以直接输入db查看用户列表db.system.users.find();查看所有用户showusers;查看所有数据库showdbs;

查看所有集合showcollections;删除当前的数据库

db.dropDatabase();删除collectiondb.集合名.drop();想知道mongodb支持哪些命令,可以直接输入help;想知道当前数据库支持哪些方法:db.help();

想知道当前集合支持哪些方法:db.user.help();user为集合名更多命令可以用帮助命令获得!创建数据库,集合

由于Mongodb不是关系型数据库文件,实际上,它并不存在传统关系型数据库中的所谓“数据库”的概念,当你第一次新增数据时,MongoDB就会以collection集合的形式进行保存和新建,而不需要你提前去建立。

1)列出当前的数据库。使用mongo命令进入数据库,使用showdbs命令查看所有的数据库,只有admin、local、2个数据库。[root@localhost/]#mongoMongoDBshellversion:2.0.2connectingto:test>showdbsadmin(empty)local(empty)2)定义新的数据库名。注意:在usemydb后,其实并没有真正的建立起来,只是表明在使用当前的数据库。>usemydbswitchedtodbmydb>showdbsadmin(empty)local(empty)3)保存数据。(隐式创建数据库和集合)定义一个collection(集合),名为“users”,然后插入数据:首先用insert语句插入一条数据,使用的是users集合,插入成功后查看所有的库,多了个mydb的库,再查看所有集合,多了个users集合,再查看刚才添加的数据,也可以查到。>db.users.insert({"_id":1,"name":"mongo"})>showdbsadmin(empty)local(empty)mydb0.0625GB>showcollectionssystem.indexesusers>db.users.find(){"_id":1,"name":"mongo"}数据库基本操作:增查删改添加数据 添加数据使用:关键字insert

或save 语法格式:

db.collname.insert({…})

db.collname.save({…})

>a={"name":"caida"}{"name":"caida"}>b={"age":24}{"age":24}>db.users.insert(a);>db.users.save(b);>db.users.find(){"_id":1,"name":"mongo"}{"_id":ObjectId("4eb2a192bf10550b2177b6f7"),"name":"caida"}{"_id":ObjectId("4eb2a199bf10550b2177b6f8"),"age":24}idkey

存储在MongoDB集合中的每个文档(document)都有一个默认的主键_id,它必须是唯一的,这个主键名称是固定的,它可以是MongoDB支持的任何数据类型,默认是ObjectId。在关系数据库的设计中,主键大多是数值型的,比如常用的int,并且更通常的是主键的取值由数据库自增获得,反观MongoDB,它在设计之初就定位于分布式存储系统,所以它原生的不支持自增主键。

在这里给大家提出一个方案: 自己定义一个函数,来让它实现id自增。 如图中代码:在插入_id时调用自己定义的函数。functioncounter(name){varret=db.counters.findAndModify({query:{_id:name},update:{$inc:{next:1}},"new":true,upsert:true});returnret.next;}

db.users.insert({_id:counter("users"),name:"id1"})//_id:1db.users.insert({_id:counter("users"),name:"id2"})//_id:2删除数据

删除数据使用:关键字remove语法格式:db.collname.remove({条件})(不写条件删除所有记录)注意:{}中也就是第一个参数,是要指定的删除条件。>db.users.remove({"name":"caida"})>db.users.find(){"_id":1,"name":"mongo"}{"_id":ObjectId("4eb2a199bf10550b2177b6f8"),"age":24}修改数据修改数据使用:关键字update语法格式:db.collname.update({条件})和删除一样,第一个参数里面是条件匹配

>db.users.update({"_id":1},{"name":"nosql"})>db.users.find(){"_id":1,"name":"nosql"}{"_id":ObjectId("4eb2a199bf10550b2177b6f8"),"age":24}使用修改器:1.$set修改器db.user.update({“_id”:ObjectId(“..”)},{“$set”:{name:”user1”}})2.$unset修改器db.user.update({name:”user1”},{$unset:{age:1}})3.$inc增加或减少1db.user.update({name:”user1”},{$inc:{age:1}})数组修改器:1.$push修改器$pushAll向数组末尾加入一个元素,如果没有就创建一个新的数组db.user.update({name:”user1”},{$push:{hobby:”football”}})2.$addToSet修改器判断一个值不在数组中就插入,存在的话不执行插入db.user.update({name:”user1”},{$addToSet:{hobby:”sing”}})相当于:db.user.update({name:”user1”,hobby:{$ne:”sing”}},{$push:{hobby:”sing”}})数组修改器:3.将$addToSet和$each组合起来,可以添加多个不同的值db.user.update({“_id”:ObjectId(”…”)},{$addToSet:{email:{$each:[“haha@163.com”,”haha@”]}}})这种情况下,使用$ne和$push是无法实现的。4.$pop修改器可以从数组的任何一端删除元素$pop:{key:1}从数组末尾删除一个元素$pop:{key:-1}从数组开头删除一个元素5.$pull修改器$pullAll基于特定条件删除元素$pull:{hobby:”football”}数组修改器:6.数组的定位修改器$若数组有多个值,我们可以通过下标直接作为键来选择元素users:[{name:”user1”,},{name:”user2”},{name:”user3”}]db.c1.update({title:”haha”},{$set:{:”user4”}})这样通过下标取很不方便。db.c1.update({:”user1”},{$set:{users.$.name:”user4”}})Upsert:Upsert是一种特殊的更新,要是没有文档符合更新条件,就创建一个新文档,如果找到了匹配的文档,则正常更新。db.user.update({name:”user1”},{name:”user2”},true)如果没有以name:”user1”为条件的记录,那么就以name:”user1”这个条件和更新文档name:”user2”为基础创建文档,也就是说,先创建一个name:”user1”的文档,然后再更新name:”user1”为name:”user2”。又例:db.math.remove();db.math.update({count:25},{$inc:{count:3}},true)先清空文档,创建一个以”count”的值为25的文档,随后将这个值加3,最终得到count为28。Save:Save是一个shell函数,相当于upsertvarx=db.user.findOne()x.num=42db.user.save(x)要是这个文档含有”_id”键,save会调用upsert,否则会调用插入。等价于:db.user.update({_id:x._id},x)更新多个文档:默认情况下,更新只能对符合匹配条件的第一个文档执行操作。要是有多个文档符合条件,其余的文档不做变化,要是所有匹配到的文档都得到更新,可以设置update的第4个参数为true。例如:假设要给所有在特定日期过生日的用户一份礼物,就可以使用多文档更新,将gift增加到他们的账号。db.user.update({birthday:”12/21/2012”},{$set:{gift:”happybirthday”}},false,true)这样就给生日为2012年12月21日的所有用户文档增加了“gift”键。想要知道多文档更新到底更新了多少文档,可以运行getLastError命令db.user.update({birthday:”12/21/2012”},{$set:{gift:”happybirthday”}},false,true)db.runCommand({getLastError:1});查询数据修改数据使用:关键字find

或findOne(查询一条)语法格式:db.collname.find({条件})(不写条件查询所有的数据)>db.users.find(){"_id":1,"name":"nosql"}{"_id":ObjectId("4eb2a199bf10550b2177b6f8"),"age":24}>db.users.find({"name":"nosql"}){"_id":1,"name":"nosql"}指定返回的键:db.user.find({name:”user1”},{“name”:1,”_id”:0})查询的结果只返回name查询条件:$lt,$gt,$lte,$gte,$ne:db.user.find({“age”:{“$gt”:20,”$lte”:50}})例如:要查找在2012年12月21日前注册的人,可以像下面这样:start=newDate(“12/21/2012”)db.user.find({“registered”:{“$lt”:start}})OR查询:$in,$or$in针对同一键的不同值,相同的还有$nin$or针对不同键例如:db.user.find({“age”:{“$in”:[10,20]}})db.user.find({“age”:{“$nin”:[20,30]}})db.user.find({“$or”:[{“name”:”user1”},{“age”:20}]})db.user.find({“$or”:[{“name”:{“$in”:[“user1”,”user2”]}},{“age”:20}]})查询条件:$not$mod$not:取反$mod:取模例如:db.user.find({“id_num”:{“$mod”:[5,1]}})返回id_num除以5余1的条件成立的结果db.user.find({“id_num”:{“$not”:{“$mod”:[5,1]}}})返回id_num除以5不余1的条件成立的结果查询条件:$exists判断键值是否存在例如:db.user.find({“y”:{“$in”:[null],$exists:1}})显示y键存在并且值为null的结果正则表达式:正则表达式能够灵活有效地匹配字符串。db.user.find({“name”:/jiege/i})查询数组:$all如果需要通过多个元素来匹配数组,就要用$all了,这样就会匹配一组元素。db.food.find({fruit:{$all:[“apple”,”banana”]}})$size:查询指定长度的数组。db.food.find({“fruit”:{“$size”:3}})$slice操作符$slice返回数组的一个子集合。例如:假设有一个博客文章的文档,要想返回前10条评论db.blog.posts.findOne({“title”:”123”},{“comm”:{“$slice”:10}})db.blog.posts.findOne({“title”:”123”},{“comm”:{“$slice”:-10}})-10表示显示后10条“$slice”:[20,10]返回从21~30条的评论$elemMatch匹配数组中的单个内嵌文档的限定条件。例如:现有博客文章若干,要找到由Joe发表的5分以上的评论。db.blog.find(){ “content”:”…”, “comments”:[ { “author”:”jiege”, “score”:5 } ]}db.blog.find({“comments”:{“$elemMatch”:{“author”:”jiege”,”score”:{“$gte”:5}}}})$where用“$where”子句可以执行任意JS作为查询的一部分。最典型的应用就是比较文档中的两个键的值是否相等。例如:有个条目列表,如果其中的两个值相等则返回文档。db.foo.insert({“apple”:1,”banana”:6,”peach”:3})db.foo.insert({“apple”:8,”peach”:4,”watermelon”:4})在第二个文档中,”peach”和”watermelon”的值相同,所以需要返回该文档。不是非常必要时,一定要避免使用”$where”查询,因为它在速度上要比常规查询慢很多。db.food.find({“$where”:function(){ for(varcurrentinthis){ for(varotherinthis){ if(current!=other&&this[current]==this[other]){returntrue; } } } returnfalse;}});游标:数据库使用游标来返回find的执行结果,客户端对游标的实现通常能够对最终结果进行有效的控制。for(i=0;i<100;i++){ db.c.insert({x:i});}varcursor=db.collection.find();while(cursor.hasNext()){ obj=cursor.next();}Cursor.hasNext()检查是否有后续结果存在,然后使用cursor.next()将其获得。Limit:要限制结果数量,可以在find()后面使用limit函数。例如:只返回3个结果db.c.find().limit(3)Skip:要略过前n个文档结果,返回余下的文档,需要使用skip函数例如:从第四个文档开始返回db.c.find().skip(3)用skip略过少量的文档还是不错的,但是要是数量非常多的话,skip就会变得很慢,所以要尽量避免。Sort:Sort用一个对象作为参数:一组键/值对,键对应文档的键名,值代表排序的方向,1为升序,-1为降序。如果指定了多个键,则按照多个键的顺序逐个排序。例如:要按照“username”升序及“age”降序排序,可以这样写。db.c.find().sort({username:1,age:-1})不用skip对结果分页:例如:要按照“date”降序显示文档。可以用如下方式获取结果的第一页:varpage1=db.foo.find().sort({“date”:-1}).limit(100)然后,可以利用最后一个文档中“date”的值作为查询条件,来获取下一页:varlatest=null;while(page1.hasNext()){ latest=page1.next(); display(latest);}varpage2=db.foo.find({“date”:{“$gt”:latest.date}});page2.sort({“date”:-1}).limit(100);索引:创建索引要使用ensureIndex方法:db.user.ensureIndex({“username”:1})对于同一个集合,同样的索引只需要创建一次,反复创建是徒劳的。创建索引的缺点就是每次插入、更新和删除时都会产生额外的开销。这是因为数据库不但需要执行这些操作,还要将这些操作在集合的索引中标记。因此要尽可能少创建索引。为内嵌文档的键建立索引和为普通的键建立索引没有什么区别。db.blog.ensureIndex({“comments.date”:1})索引方向:传递给ensureIndex的文档形式是:一组值为1或-1的键,表示索引创建的方向。若索引只有一个键,则方向无关紧要。若有多个键,就要考虑方向问题了。例如:现需要对用户名进行升序搜索,对年龄做降序搜索db.user.ensureIndex({“name”:1,”age”:-1})

索引名称:ensureIndex可以指定索引的名称:db.user.ensureIndex({“name”:1},{”name”:”index_name”})唯一索引:db.user.ensureIndex({“username”:1},{“unique”:true})创建唯一索引时删除重复文档:db.user.ensureIndex({“username”:1},{“unique”:true,”dropDups”:true})Explain:Explain会返回查询使用的索引情况(如果有的话),耗时及扫描文档数的统计信息。db.user.find().explain()索引管理:索引的元信息存储在每个数据库的system.indexes集合中。删除索引:db.runCommand({“dropIndexes”:”user”,”index”:”name”})db.user.dropIndex({“name”:1})db.user.dropIndexes()聚合:CountCount是最简单的聚合工具,返回集合中的文档数量。db.user.count();db.user.insert({“x”:1})db.user.count()也可以传递查询,Mongo则会计算查询结果的数量:db.user.insert({“x”:2})db.user.count()db.user.count({“x”:1}) 增加查询条件会使得count变慢Distinct:用来找出给定键的所有不同的值,使用时必须制定集合和键。db.runCommand({“distinct”:”people”,”key”:”age”})例如:获取所有不同的年龄{“name”:”Ada”,”age”:20}{“name”:”fred”,”age”:30}{“name”:”susan”,”age”:20}{“name”:”andy”,”age”:15}db.runCommand({“distinct”:”people”,”key”:”age”}){“values”:[15,20,30],”ok”:1}数据库命令:getLastError:来查看一个更新对多少个文档起作用:db.count.update({x:1},{$inc:{x:1}},false,true)db.runCommand({getLastError:1})Drop:删除一个集合,等同于drop()db.$cmd.findOne({“drop”:”test”})db.collname.drop()访问有些命令需要有管理员权限,必须在admin数据库里面运行,如果在别的数据库里运行这样的命令,会得到“拒绝访问”的错误。性能优化explain执行计划

MongoDB提供了一个explain命令让我们获知系统如何处理查询请求。利用explain命令我们可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。

>db.t5.ensureIndex({name:1})>db.t5.ensureIndex({age:1})>db.t5.find({age:{$gt:45}},{name:1}).explain(){"cursor":"BtreeCursorage_1", 返回游标类型(BasicCursor或BtreeCursor)"nscanned":0, 被扫描的文档数量"nscannedObjects":0,"n":0, 返回的文档数量"millis":0, 耗时(毫秒)"nYields":0,"nChunkSkips":0,"isMultiKey":false,"indexOnly":false,"indexBounds":{ 所使用的索引"age":[[45,1.7976931348623157e+308]]

}}CappedCollection固定集合简单介绍 cappedcollections是性能出色的有着固定大小的集合,以LRU(LeastRecentlyUsed最近最少使用)规则和插入顺序进行age-out(老化移出)处理,自动维护集合中对象的插入顺序,在创 建时要预先指定大小。如果空间用完,新添加的对象将会取代集合中最旧的对象。

永远保持最新的数据。功能特点 可以插入及更新,但更新不能超出collection的大小,否则更新失败。不允许删除,但是可以调用drop()删除集合中的所有行,但是drop后需要显式地重建集合。在32位机上一个cappedcollection的最大值约482.5M,64位上只受系统文件大小的限制。

属性及用法属性1:对固定集合进行插入速度极快属性2:按照插入顺序的查询输出速度极快。属性3:能够在插入最新数据时,淘汰最早的数据。用法1:储存日志信息。用法2:缓存一些少量的文档。创建固定集合不像普通集合,固定集合需要显式的创建使用createCollection命令来创建。db.createCollection(“my_collection”,{capped:true,size:10000})创建一个集合为‘my_collection’的固定集合,大小为10000字节。还可以限定文档个数。加上Max:100属性。注意:指定文档上限,必须指定大小。文档限制是在容量没满时进行淘汰,要是满了,就根据容量限制来进行淘汰。转换集合把普通的集合转换成固定集合需要使用convertToCapped命令db.runCommand({convertToCapped:”test”,size:10000})把test普通集合转换为固定集合,大小为10000字节。自然排序固定集合文档按照插入顺序储存的,默认情况下查询就是按照插入顺序返回的,也可以使用$natural

调整返回顺序。db.my_collection.find().sort({“$natural”:1})1表示默认顺序,-1则相反。GridFSGridFS是一种在MongoDB中存储大二进制文件的机制,使用GridFS的原因有以下几种:储存巨大的文件,比如视频、高清图片等。利用GridFS可以简化需求。GridFS会直接利用已经建立的复制或分片机制,故障恢复和扩展都很容易。GridFS可以避免用户上传内容的文件系统出现问题。GridFS不产生磁盘碎片。GridFS使用两个表来存储数据:

files

包含元数据对象chunks

包含其他一些相关信息的二进制块 为了使多个GridFS命名为一个单一的数据库,文件和块都有一个前缀,默认情况下,前缀是fs,所以任何默认的GridFS存储将包括命名空间fs.files

和fs.chunks。各种第三方语言可以更改其前缀。使用GridFS

mongofilesmongofiles是从命令行操作GridFS的一种工具

三个命令:put(存储)get(取得)list(列表)例如:我们将”testfile”这个文件存到库里面,具体用法如下:[root@localhostbin]#./mongofilesputtestfileconnectedto:addedfile:{_id:ObjectId('4fc60175c714c5d960fff76a'),filename:"testfile",chunkSize:262144,uploadDate:newDate(1338376565745),md5:"8addbeb77789ae6b2cb75deee30faf1a",length:16}done!下面我们查一下看库里有哪些GridFS文件,在”mongofiles”后加一个参数”list”即可接下来我们进库里看一下是否有新的东西[root@localhostbin]#./mongofileslistconnectedto:testfile16--大小>showcollectionsfs.chunks--上文提到的fs.chunksfs.files--上文提到的fs.files我们继续查看fs.files中的内容字段说明:Filename: 存储的文件名chunkSize: chunks分块的大小uploadDate: 入库时间md5: 此文件的md5码length: 文件大小,单位”字节”fs.files中存储的是一些基础的元数据信息db.fs.files.find(){"_id":ObjectId("4fc60175c714c5d960fff76a"),"filename":"testfile","chunkSize":262144,"uploadDate":ISODate("2012-05-30T11:16:05.745Z"),"md5":"8addbeb77789ae6b2cb75deee30faf1a","length":16}我们继续查看中的内容_id: 块自身的idfiles_id: 包含这个块的元数据文档文件idn: 它代表的是chunks的序号,此序号从0开data:组成文件块的二进制文件fs.chunks中存储的是一些实际的内容数据信息>db.fs.chunks.find(){"_id":ObjectId("4fc60175cf1154905d949336"),"files_id":ObjectId("4fc60175c714c5d960fff76a"),"n":0,"data":BinData(0,"SGVyZSBpcyBCZWlqaW5nCg==")}我们即然能将此文件存进去,我们就应该有办法将其取出来,下面看一下实例:[root@localhostbin]#rmtestfilerm:是否删除一“testfile”?y --先删文件[root@localhostbin]#./mongofilesgettestfile --将其从库里取出来connectedto:donewriteto:testfile[root@localhostbin]#md5sumtestfile --校验md5,结果跟库里相同GridFS:存储文件上传文件:Mongofilesputfoo.txt查看文件:Mongofileslist下载文件:Mongofilesgetfoo.txt搜索文件:Search用来按文件名查找GridFS中的文件删除文件:Delete是从GridFS中删除一个文件。优化器profileMongoDBDatabaseProfiler

是一种慢查询日志功能,可以作为我们优化数据库的依据。

开启Profiling功能有两种方式可以控制Profiling的开关和级别。启动MongoDB时加上–profile=级别即可。在客户端调用db.setProfilingLevel(级别)命令来实时配置。Profiler信息保存在file

中。我们可以通过db.getProfilingLevel()命令来获取当前的Profile级别.具体操作:上面profile的级别可以取0,1,2三个值,它们的表示:0–

不开启1–

记录慢命令(默认为>100ms)2–

记录所有命令>db.setProfilingLevel(2);

{"was":0,"slowms":100,"ok":1}>db.getProfilingLevel();2Profile在级别1时会记录慢命令,上面的默认值为100ms,有默认就有设置,其设置方法和级别有两种方法:一种是通过添加–slowms

启动参数配置。db.setProfilingLevel时加上第二个参数。那么这个慢的定义是什么?可以理解比较耗时的命令,如一个查询耗时10毫秒,就会被记录下来。db.setProfilingLevel(1,10);查看具体信息:字段说明:ts: 该命令在何时执行info:

本命令的详细信息reslen: 返回结果集的大小nscanned: 本次查询扫描的记录数nreturned: 本次查询实际返回的结果集millis: 该命令执行耗时,以毫秒记

一个比较简洁的命令showProfile,可列出最近5

条执行时间超过1ms的Profile记录>file.find().sort({$natural:-1}).limit(1){"ts":ISODate("2012-05-20T16:50:36.321Z"),"info":"queryfilereslen:1219nscanned:8\nquery:{query:{},orderby:{$natural:-1.0}}nreturned:8bytes:1203","millis":0}优化方案1:创建索引在查询条件的字段上,或者排序条件的字段上创建索引,可以显著提高执行效率。db.posts.ensureIndex({ts:1});

优化方案2:限定返回结果条数使用limit()限定返回结果集的大小,可以减少databaseserver的资源消耗,可以减少网络传输数据量。db.posts.find().sort({ts:-1}).limit(10);

优化方案3:查询使用到的字段,不查询所有字段优化方案4:采用cappedcollectioncappedCollections比普通Collections的读写效率高优化方案5:采用ProfilingProfiling功能肯定是会影响效率的,但是不太严重,原因是他使用的是file来记录,file是一个cappedcollection这种collection在操作上有一些限制和特点,但是效率更高。db.posts.find({},{ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);性能监控通过对数据库的性能监控,能够更好的了解数据库的工作状态,从而进行优化。介绍几个性能监控的工具:Mongosniff此工具可从底层监控到底有哪些命令发送给MongoDB去执行。./mongosniff--sourceNETlo

它是实时动态监视的,需要打开另一个客户端进行命令操。可以将这些数据输出到一个日志文件中,那么就可以保留下所有数据库操作的历史记录,对于后期的性能分析和安全审计等工作将是一个巨大的贡献。。Mongostat此工具可以快速的查看某组运行中的MongoDB实例的统计信息,也需要在打开一个客户端进行命令操作:用法如下:[root@localhostbin]#./mongostat

下面是执行结果(部分):

[root@localhostbin]#./mongostatinsertqueryupdatedeletelocked%idxmiss%qr|qwar|awconntime*0*0*0*0000|01|0401:19:15*0*0*0*0000|01|0401:19:16*0*0*0*0000|01|0401:19:17字段说明:

insert: 每秒插入量query: 每秒查询量update: 每秒更新量delete: 每秒删除量locked: 锁定量qr|qw:客户端查询排队长度(读|写)ar|aw:活跃客户端量(读|写)conn: 连接数time: 当前时间它每秒钟刷新一次状态值,提供良好的可读性,通过这些参数可以观察到一个整体的性能情况。db.serverStatus()这个命令是最常用也是最基础的查看实例运行状态的命令之一,下面我们看一下它的输出:>db.serverStatus(){"host":"localhost.localdomain","version":"1.8.1",--服务器版本

"process":"mongod","uptime":3184,--启动时间(秒)"uptimeEstimate":3174,"localTime":ISODate("2012-05-28T11:20:22.819Z"),"globalLock":{"totalTime":3183918151,"lockTime":10979,"ratio":0.000003448267034299149,"currentQueue":{"total":0,--当前全部队列量

"readers":0,--读请求队列量。。。。。。。db.statsdb.stats查看数据库状态信息。使用样例如下:

>db.stats(){"db":"test","collections":7,--collection数量

"objects":28,--对象数量

"avgObjSize":50.57142857142857,--对象平均大小

"dataSize":1416,--数据大小

"storageSize":31744,--数据大小(含预分配空间)"numExtents":7,--事件数量

"indexes":7,--索引数量

"indexSize":57344,--索引大小

"fileSize":50331648,--文件大小

"ok":1--stats是否正常}第三方工具:MongoDB从一面世就得到众多开源爱好者和团队的重视,在常用的监控框架如cacti、Nagios、Zabbix

等基础上进行扩展,进行MongoDB的监控都是非常方便的。数据导出、数据导入 作为DBA(管理员),经常会碰到导入导出数据的需求,下面就介绍实用工具:数据导出

mongoexport数据导入

mongoimport

数据导出命令mongoexport假设库里有一张user表,里面有2条记录,我们要将它导出

>usemy_mongodbswitchedtodbmy_mongodb>db.user.find();{"_id":ObjectId("4f81a4a1779282ca68fd8a5a"),"uid":2,"username":"Jerry","age":100}{"_id":ObjectId("4f844d1847d25a9ce5f120c4"),"uid":1,"username":"Tom","age":25}常用导出方法参数说明:-d指明使用的库,“my_mongodb”

-c指明要导出的表,“user”

-o指明要导出的文件名,“user.dat”

从上面可以看到导出的方式使用的是JSON的样式

[root@localhostbin]#./mongoexport-dmy_mongodb-cuser-ouser.dat

connectedto:exported2records[root@localhostbin]#catuser.dat{"_id":{"$oid":"4f81a4a1779282ca68fd8a5a"},"uid":2,"username":"Jerry","age":100}{"_id":{"$oid":"4f844d1847d25a9ce5f120c4"},"uid":1,"username":"Tom","age":25}导出CSV格式的文件参数说明:-csv指要要导出为csv格式-f指明需要导出哪些例更详细的用法可以mongoexport–help查看

[root@localhostbin]#./mongoexport-dmy_mongodb-cuser--csv-fuid,username,age

-ouser_csv.datconnectedto:exported2records[root@localhostbin]#catuser_csv.datuid,username,age2,"Jerry",1001,"Tom",25数据导入命令mongoimport导入JSON数据测试时可以先将原表删掉,以便更好的演示,导入时会自动隐式创建数据库结构。[root@localhostbin]#./mongoimport-dmy_mongodb-cuseruser.dat

connectedto:imported2objects导入CSV数据

参数说明:-type 指明要导入的文件格式-headerline 表明不导入第一行,因为第一行是列名-file 指明要导入的文件路径注意:CSV格式良好,主流数据库都支持导出为CSV的格式,所以这种格式非常利于异构数据迁移。

[root@localhostbin]#./mongoimport-dmy_mongodb-cuser--typecsv-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论