MongoDB實用教程

---------------------------------------------------------------------------------------------------------------
[版權申明:本文系做者原創,轉載請註明出處]
文章出處: http://blog.csdn.net/sdksdk0/article/details/51765219
做者:朱培   ID:sdksdk0
---------------------------------------------------------------------------------------------------------------
本文主要內容包括nosql的簡介、mongodb的簡介、mongodb的體系結構、mongodb在linux和window中的安裝配置、安全控制、mongodb的基本數據操做(包括建立數據庫,建表,增刪改查等)、索引(查詢索引、全文索引,地理位置索引等7大索引方式)的使用等主要內容。要求掌握mongodb的雙平臺配置,基本數據操做,索引的使用,安全控制,索引分析等。

1、NoSql簡介

NoSQL,泛指非關係型的數據庫。隨着互聯網web2.0網站的興起,傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,而非關係型的數據庫則因爲其自己的特色獲得了很是迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題。

傳統的結構化的數據:固定長度,固定的類型 linux

非結構化的數據:doc,ppt,pdf.c++

nosql(不只僅是數據庫能夠乾的事情),指的是非關係型數據庫,以鍵值對存儲,它的結構不固定,沒一條記錄能夠有不同的鍵,每條記錄能夠根據須要增長一些本身的鍵值對,這樣就不會侷限於固定的結構,能夠減小一些時間和空間的開銷。web

常見的有:CouchDB、Redis、MongoDB、Neo4j、HBase、BigTablesql


2、MongoDB簡介

MongoDB 是一個基於分佈式文件存儲的數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。
MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。

是用c++寫的非關係型數據庫,特色是高性能、易部署、易使用,存儲數據很是方便,面向集合存儲,易於存儲對象類型的數據,模式自由,支持動態查詢,支持徹底索引,包含內部對象,支持複製和故障恢復,使用高效的二進制數據存儲,包括大型對象,文件存儲格式爲BSON(一種json的擴展)。mongodb


3、MongoDB的體系結構

MongoDB 的邏輯結構是主要由:文檔(document)、集合(collection)和數據庫(database)這三部分組成的。
MongoDB 的文檔(document),至關於關係數據庫中的一行記錄
集合(collection),至關於關係型數據庫中的表的概念
文檔(document)、集合(collection)、數據庫(database)的層次結構以下圖:



4、MongoDB安裝配置


4.1 linux中安裝

這裏服務器用ubuntu15.10,在secureCRT中鏈接這個ubuntu。 首先使用 rz 上傳window中從官網(https://www.mongodb.com/)下載的mongodb安裝文件。數據庫

解壓這個文件:json

tar -xvzf  mongodb-linux-x86_64-ubuntu1404-3.2.7.tgz

//重命名ubuntu

mv mongodb-linux-x86_64-ubuntu1404-3.2.7  mongodb3.2

在目錄中新建data,log和conf文件夾,在cong中新建mongodb.config,內容以下:數組

port=27017
dbpath=data
logpath=log/mongod.log
fork=true

啓動服務:瀏覽器

./bin/mongod -f conf/mongodb.config

鏈接: mongo客戶端鏈接

bin/mongo 192.168.44.131:27017/test


在linux中鏈接成功:


網頁端:能夠在瀏覽器中查看一下:http://www.192.168.44.131:27017/


關閉:

db.shutdownServer();

查看端口號: ps -ef|grep mongod|grep 27017

kill 相應端口



4.2 window中安裝

安裝過程與linux基本相同,就是配置一下環境變量,建立data,log,conf目錄等。

若是是在window中,啓動成功會是這樣:



瀏覽器中訪問:http://www.localhost:28017/   

在mongodb有的版本中會提示端口號加1000的,因此我終於演示的時候是28017端口。



5、MongoDB安全控制


建立用戶

安全性從高到低: 物理隔離、網絡隔離、防火牆隔離、用戶名密碼。

開啓權限認證: 在配置文件中——mongodb.config中設置:

auth=true

建立用戶:(2.6以前是addUser)

createUser{user:" ", pwd:"cleartext password", customData:{ }, roles:[{role:" ", db:" "}] }

例如:建立用戶名爲zp,密碼爲a的用戶

db.createUser({user:"zp",pwd:"a",roles:[{role:"userAdmin",db:"admin"},{role:"read",db:"test"}]})

登錄:

bin/mongod 192.168.44.131 -u zp -p a

角色類型

數據庫角色 :read, readWrite,dbAdmin, dbOwner, userAdmin

集羣角色:clusterAdmin,clusterManager

備份角色:backup,restore

其餘:DBAdminAnyDatabase


6、MongoDB基本數據操做

//查看數據庫

show dbs

//查看錶

show tables

//建立數據庫

use one_db


//插入數據 格式:db.表名.insert({ json格式的數據 }) 例如:

db.one_db_collection.insert({ x:1 })

//查詢剛纔寫入的表

show collections

查詢具體內容 db.onedbcollection.find()

運行結果爲:

{ "_id" : ObjectId("576fdc6e8224cdb105bcb3df"), "x" : 1 }

id是系統自動生成的,每條數據的id是惟一的 咱們還能夠本身給_id賦值:

db.one_db_collection.insert({x:2,_id:1})

批量插入多條數據

for(i=4;i<20;i++)db.one_db_collection.insert({x:i})

統計條數:

db.one_db_collection.find().count()

過濾排序:

db.one_db_collection.find().skip(5).limit(3).sort({x:1})

從x:1開始,過濾前5條數據,而後從第6條開始選取3條數據,並進行排序。

演示效果以下:



//更新數據

db.one_db_collection.update({x:1},{x:100})

當插入這樣的一條數據的時候:

db.one_db_collection.insert({x:100,y:100,z:100})

這個時候更新y的值,須要加$set符號:

db.one_db_collection.update({z:100},{$set:{y:200}})

當更新一條不存在的數據的時候,若是加上true則會自動建立一條這個不存在的數據

db.one_db_collection.update({y:100},{y:300},true)

效果以下:



//一次性更新多條相同的數據

db.one_db_collection.update({ y:300},{$set:{y:301}},false,true)

若是有多條重名的且update時未加true,則只刪除相同數據中的第一條數據。




//數據的刪除

db.one_db_collection.remove({y:301})

//刪除表

db.one_db_collection.drop()

7、查詢索引


//查看當前表中索引

db.one_db_collection.getIndexes()

//建立索引

db.one_db_collection.ensureIndex({x:1})

x:1表明正向排序,x:-1表明逆向排序。若是文檔數目較大,則建立索引時間會較長。若是系統中已經有不少文檔了,這個時候就不能使用這個命令去建立索引了,不然嚴重影響數據庫性能。 咱們通常須要在使用數據庫以前就要把索引建立完畢。 使用索引能夠明顯加快查詢速度。



索引的屬性 :

名字,由name指定;惟一性,unique指定;稀疏性,sparse指定

db.collection.ensureIndex({},{name:""})
db.collection.ensureIndex({},{unique:true/false}) 
db.collection.ensureIndex({},{sparse:true/false})

索引的類型

  • 1:_id索引
  • 2:單鍵索引
  • 3:多鍵索引
  • 4:複合索引
  • 5:過時索引
  • 6:全文索引
  • 7:地理位置索引

—id索引:是絕大多數集合默認創建的索引,對於每一個插入的數據,MongoDB都會自動生成一條惟一的id字段。

db.one_db_collection.ensureIndex({x:1})

例如查詢結果爲: { "_id" : ObjectId("576fecca8224cdb105bcb3f1"), "x" : 1 }

多鍵索引: 1.多鍵索引與單鍵索引建立形式相同,區別在於字段的值。 1)單鍵索引:值爲一個單一的值,如字符串,數字或日期。 2)多鍵索引:值具備多個記錄,如數組。

db.twodb.insert({x:[1,2,3,4,5]})

複合索引:

db.twodb.ensureIndex({x:1,y:1})

過時索引: 此索引過一段時間會過時,索引過時後,相應的數據會被刪除,適合存儲一些在一段時間以後會失效的數據,好比用戶登陸信息.

db.twodb.ensureIndex({time:1},{expireAfterSeconds:60})  //過時時間設置爲60秒

db.twodb.insert({time:new Date()})

db.twodb.find() //60秒後就查不到數據了

過時索引的限制: 1.存儲在過時索引字段的值必須是指定的時間類型,必須是ISODate或者ISODate數組,不能使用時間戳,不然不能自動刪除。 例如 >db.twodb.insert({time:1}),這種是不能被自動刪除的 2.若是指定了ISODate數組,則按照最小的時間進行刪除。 3.過時索引不能是複合索引。由於不能指定兩個過時時間。 4.刪除時間是不精確的。刪除過程是由MongoDB的後臺進程每60s跑一次的,並且刪除也須要必定時間,因此存在偏差。



8、全文索引


對字符串與字符串數組建立全文可搜索的索引

建立全文索引的方法

db.threedb.ensureIndex({key:"text"})
db.threedb.ensureIndex({key_1:"text",key_2:"text"})
db.threedb.ensureIndex({"$**":"text"})

演示建立一個全文索引

db.threedb.ensureIndex({"article":"text"})

插入幾條演示數據

db.threedb.insert({"article":"aa  bb cc dd ee  11"})
db.threedb.insert({"article":"aa  dd rr jj ff  22"})
db.threedb.insert({"article":"aa  oo  qq tt kk 33"})

使用全文索引進行查詢 //搜索標題中有aa的記錄

db.threedb.find({$text:{$search:"aa"}})

//多個關鍵字查找,查找只要含有dd qq 33中任何一個的就能夠("或"關係)

db.threedb.find({$text:{$search:"dd  qq 33"}})

//查找包含dd qq可是不包含33的數據,在關鍵詞前面加上-號表明不包含:

db.threedb.find({$text:{$search:"dd  qq -33"}})



//"與"關係查找,既包含aa 又包含qq的數據

db.threedb.find({$text:{$search:"\"aa\" \"qq\" "}})



//類似度查詢

使用$meta:{score:{$meta:"textScore"}} 寫在查詢條件後面能夠返回結果的類似度,與sort一塊兒使用,能夠達到很好的實用效果。

db.threedb.find({$text:{$search:"dd qq 33"}},{score:{$meta:"textScore"}})

db.threedb.find({$text:{$search:"dd  qq 33"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})



全文搜索的使用限制

  1. 每次查詢,只能指定一個$text查詢
  2. $text查詢不能出如今$nor查詢中
  3. 查詢中若是包含了$text, hint再也不起做用
  4. MongoDB全文索引還不支持中文

9、地理位置索引


將一些點的位置存儲在Mongodb數據庫中,而且建立索引,這些就是地理位置索引,以後就能夠按照位置來查找其餘的點了!

分類 1.2D索引,用於存儲和查找平面上的點。 2.2Dsphere索引,用於存儲和查找球面上的點。

查找方式: 1:查找距離某個點必定距離內的點 2:查找包含在某個區域內的點


2D索引

2D地理位置索引建立方式 db.collection.ensureIndex({w:"2d"}) 2D地理位置索引的取值範圍以及表示方法 經緯度[經度,緯度] 經緯度取值範圍 經度[-180,180] 緯度[-90,90]

//建立2d索引

db.location.ensureIndex({"w":"2d"})

//插入數據 db.location.insert({w:[20,30]}) db.location.insert({w:[160,90]}) db.location.insert({w:[20,90]}) db.location.insert({w:[80,120]})

一、使用$near 查詢距離某個點最近的點 db.collection.find({w:{$near:[x,y]}}) 使用$near默認返回最近的100個點,可使用$maxDistance:x 限制返回的最遠距離 查詢距離(1,1)最近的點

db.location.find({w:{$near:[1,1]}})

查詢在最遠距離爲100的點

db.location.find({w:{$near:[1,1],$maxDistance:100}})



二、使用$geoWithin 查詢某個形狀內的點 形狀的表示方式: 1. $box 矩形,使用{$box:[[x1,y1],[x2,y2]]} 2. $center 圓形,使用 {$center:[[x,y],r]} 3. $polygon 多邊形,使用 {$polygon:[[x1,y1],[x2,y2],[x3,y3]]}

//查詢在(0,0)(80,80)之間的位置的數據 一個矩形

db.location.find({w:{$geoWithin:{$box:[[0,0],[80,80]]}}})


//圓形區域內,原心爲(20,30),半徑是80

db.location.find({w:{$geoWithin:{$center:[[20,30],80]}}})


//多邊形

db.location.find({w:{$geoWithin:{$polygon:[[0,0],[40,30],[80,100],[30,60]]}}})



//geoNear的使用 格式: db.runCommand({geoNear: ,near:[x,y],minDistance:maxDistance:num:})

查詢距離(1,1)最遠距離爲100的,最多返回1條數據

db.runCommand({geoNear:"location",near:[1,1],maxDistance:100,num:1})



球面地理位置索引

2dsphere索引

GeoJSON:描述一個點,一條直線,多邊形等形狀。 格式: {type:'', coordinates:[list]} GeoJSON查詢可支持多邊形交叉點等,支持MaxDistance 和 MinDistance

db.collection.ensureindex({key: '2dsphere'})

10、索引構建狀況分析


如何評判當前索引構建狀況: 1.mongostat 工具

使用mongostat -h [ip]:端口 例如:

bin/mongostat  -h  192.168.44.131:27017


idx miss和qr|qw是須要咱們重點關注的地方。

2.profile集合

db.getProfilingStatus()
db.getProfilingLevel()

當level爲0表明profiling是關閉的. 級別爲1時會記錄全部超過slowms中設定的數目的操做。 級別爲2時會記錄你的全部操做。

3.日誌分析

在配置文件中——mongodb.config中設置:

verbose=VVVVV

設置日誌,5個v記錄最詳細的數據,1個v記錄簡單的日誌信息。1到5個v來進行設置。

4.使用explain查詢分析器分析

db.collection.find({x:1}).explain()

{ "cursor" : "BasicCursor", --使用的遊標 "isMultiKey" : false, "n" : 1, "nscannedObjects" : 100000, --掃描的數據量 "nscanned" : 100000, --包含索引的掃描量 "nscannedObjectsAllPlans" : 100000, "nscannedAllPlans" : 100000, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 781, "nChunkSkips" : 0, "millis" : 25, --查詢消耗時間(毫秒) "server" : "XXX", "filterSet" : false }



11、總結

1:爲何有這麼多種索引?

不一樣的狀況下使用對應狀況下的索引,可讓查詢速度更快,可使查詢獲得進一步的優化。


2:何時使用什麼索引纔是合適的? 

簡單的說,索引就比如一本書的目錄,你只要瀏覽標題就能夠快速的找到具體內容是放在哪一頁的。也就是說用find()查找時不用直接去搜索表,只要查找索引,就能夠直接定位到你想查找的內容位置。索引帶來的方便不是免費的,是以每次插入或更新(至關於刪除並插入)時都要維護索引爲代價的。因此若是一張表更可能是用於查詢而不多插入,那麼就能夠創建儘可能多的索引以優化查詢性能。相反若是一張表要常常插入或更新,則儘量少用索引,有時甚至連主鍵都不建。


3:怎麼判斷索引創建的合適與否?

索引的創建必須慎重,對每一個索引的必要性都應該通過仔細分析,要有創建的依據.由於太多的索引與不充分、不正確的索引對性能都毫無益處:在表上創建的每一個索引都會增長存儲開銷,索引對於插入、刪除、更新操做也會增長處理上的開銷.另外,過多的複合索引,在有單字段索引的狀況下,通常都是沒有存在價值的;相反,還會下降數據增長刪除時的性能,特別是對頻繁更新的表來講,負面影響更大.

相關文章
相關標籤/搜索