




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業保安合同協議
- 餐廳洗碗工合同協議書
- 水果配送合同協議
- 投資合同到期后續簽協議
- 合同拆分協議蓋章
- 拍攝保密協議合同
- 代租車協議合同
- 商務合同財產協議
- 合同繼簽協議
- 鐵路代發協議合同
- 快遞小哥交通安全課件
- 2025年青海能源投資集團有限責任公司招聘筆試參考題庫含答案解析
- 2025年河南建筑職業技術學院單招職業技能測試題庫審定版
- 2026年版廣西高等職業教育考試(新職教高考)新聞傳播大類《攝影攝像》模擬試卷(第1套)
- 山東省煙臺市第二中學等校2021-2022學年高二下學期期中考試歷史試題(原卷版)
- DB14-T 2779-2023 營造林工程監理規范
- 學校行政管理中的溝通藝術與效率
- 二零二五版風力發電工程監理服務合同示范文本3篇
- 第十八章 平行四邊形 評估測試卷(含答案)2024-2025學年數學人教版八年級下冊
- 菌劑銷售合同(2025年)
- AI技術助力小學生閱讀能力培養的實踐案例分析
評論
0/150
提交評論