傳統的結構化的數據:固定長度,固定的類型 linux
非結構化的數據:doc,ppt,pdf.c++
nosql(不只僅是數據庫能夠乾的事情),指的是非關係型數據庫,以鍵值對存儲,它的結構不固定,沒一條記錄能夠有不同的鍵,每條記錄能夠根據須要增長一些本身的鍵值對,這樣就不會侷限於固定的結構,能夠減小一些時間和空間的開銷。web
常見的有:CouchDB、Redis、MongoDB、Neo4j、HBase、BigTablesql
是用c++寫的非關係型數據庫,特色是高性能、易部署、易使用,存儲數據很是方便,面向集合存儲,易於存儲對象類型的數據,模式自由,支持動態查詢,支持徹底索引,包含內部對象,支持複製和故障恢復,使用高效的二進制數據存儲,包括大型對象,文件存儲格式爲BSON(一種json的擴展)。mongodb
這裏服務器用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 相應端口
安裝過程與linux基本相同,就是配置一下環境變量,建立data,log,conf目錄等。
若是是在window中,啓動成功會是這樣:
瀏覽器中訪問:http://www.localhost:28017/
在mongodb有的版本中會提示端口號加1000的,因此我終於演示的時候是28017端口。
安全性從高到低: 物理隔離、網絡隔離、防火牆隔離、用戶名密碼。
開啓權限認證: 在配置文件中——mongodb.config中設置:
auth=true
建立用戶:(2.6以前是addUser)
createUser{user:"
例如:建立用戶名爲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
//查看數據庫
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()
//查看當前表中索引
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})
—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跑一次的,並且刪除也須要必定時間,因此存在偏差。
對字符串與字符串數組建立全文可搜索的索引
建立全文索引的方法
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"}})
全文搜索的使用限制
將一些點的位置存儲在Mongodb數據庫中,而且建立索引,這些就是地理位置索引,以後就能夠按照位置來查找其餘的點了!
分類 1.2D索引,用於存儲和查找平面上的點。 2.2Dsphere索引,用於存儲和查找球面上的點。
查找方式: 1:查找距離某個點必定距離內的點 2:查找包含在某個區域內的點
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:
查詢距離(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'})
如何評判當前索引構建狀況: 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 }
1:爲何有這麼多種索引?
不一樣的狀況下使用對應狀況下的索引,可讓查詢速度更快,可使查詢獲得進一步的優化。
2:何時使用什麼索引纔是合適的?
簡單的說,索引就比如一本書的目錄,你只要瀏覽標題就能夠快速的找到具體內容是放在哪一頁的。也就是說用find()查找時不用直接去搜索表,只要查找索引,就能夠直接定位到你想查找的內容位置。索引帶來的方便不是免費的,是以每次插入或更新(至關於刪除並插入)時都要維護索引爲代價的。因此若是一張表更可能是用於查詢而不多插入,那麼就能夠創建儘可能多的索引以優化查詢性能。相反若是一張表要常常插入或更新,則儘量少用索引,有時甚至連主鍵都不建。
3:怎麼判斷索引創建的合適與否?
索引的創建必須慎重,對每一個索引的必要性都應該通過仔細分析,要有創建的依據.由於太多的索引與不充分、不正確的索引對性能都毫無益處:在表上創建的每一個索引都會增長存儲開銷,索引對於插入、刪除、更新操做也會增長處理上的開銷.另外,過多的複合索引,在有單字段索引的狀況下,通常都是沒有存在價值的;相反,還會下降數據增長刪除時的性能,特別是對頻繁更新的表來講,負面影響更大.