1. 程式人生 > >天道酬勤,地道酬善,人道酬誠,商道酬信,業道酬精

天道酬勤,地道酬善,人道酬誠,商道酬信,業道酬精

本文目錄:

1.MongoDB簡介

2.MongoDB安裝

3.MongoDB圖形化管理工具

4.MongoDB的欄位型別

5.MongoDB的基本操作

6.MongoDB的查詢方式

7.MongoDB高階操作

8.MongoDB的安全

9.MongoDB的複製

10.mongoDB的備份與恢復

1.MongoDB簡介

MongoDB 是一個基於分散式 檔案儲存的NoSQL資料庫
由C++語言編寫,執行穩定,效能高
旨在為 WEB 應用提供可擴充套件的高效能資料儲存解決方案
檢視官方網站:https://www.mongodb.com/

MongoDB特點:
模式自由 :可以把不同結構的文件儲存在同一個資料庫裡
面向集合的儲存

:適合儲存 JSON風格檔案的形式
完整的索引支援:對任何屬性可索引
複製和高可用性:支援伺服器之間的資料複製,支援主-從模式及伺服器之間的相互複製。複製的主要目的是提供冗餘及自動故障轉移
自動分片:支援雲級別的伸縮性:自動分片功能支援水平的資料庫叢集,可動態新增額外的機器
豐富的查詢:支援豐富的查詢表達方式,查詢指令使用JSON形式的標記,可輕易查詢文件中的內嵌的物件及陣列
快速就地更新:查詢優化器會分析查詢表示式,並生成一個高效的查詢計劃
高效的傳統儲存方式:支援二進位制資料及大型物件(如照片或圖片)

基本:

MongoDB將資料儲存為一個文件,資料結構由鍵值(key=>value)對組成

MongoDB文件類似於JSON物件,欄位值可以包含其他文件、陣列、文件陣列

名詞:

SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 資料庫
table collection 資料庫表/集合
row document 資料記錄行/文件
column field 資料欄位/域
index index 索引
table joins 表連線,MongoDB不支援
primary key primary key 主鍵,MongoDB自動將_id欄位設定為主鍵
三元素:資料庫,集合,文件
集合就是關係資料庫中的表
文件對應著關係資料庫中的行


文件,就是一個物件,由鍵值對構成,是json的擴充套件Bson形式

{'name':'Tony','gender':'男'}
集合:類似於關係資料庫中的表,儲存多個文件,結構不固定,如可以儲存如下文件在一個集合中
{'name':'Tony','gender':'男'}
{'name':'kate','age':18}
{'book':'jack','heros':'108'}
資料庫:是一個集合的物理容器,一個數據庫中可以包含多個文件
一個伺服器通常有多個數據庫

2.MongoDB安裝

下載mongodb的版本,兩點注意
根據業界規則,偶數為穩定版,如1.6.X,奇數為開發版,如1.7.X
32bit的mongodb最大隻能存放2G的資料,64bit就沒有限制

ubuntu安裝

1.安裝:

sudo apt-get install mongodb

等待安裝之後輸入

mongo --version


檢視mongo版本,筆者安裝的是 2.6.10

2.啟動和關閉mongodb

service mongodb start
service mongodb stop
預設MongoDB是隨Ubuntu啟動自動啟動的。 

檢視是否啟動成功:

pgrep mongo -l   #英文字母l

3.進入mongo
mongo

輸入mongo之後,預設連線test資料庫

db:檢視當前資料庫名稱
show dbs:顯示資料庫列表 
show collections:顯示當前資料庫中的集合(類似關係資料庫中的表table) 
show users:顯示所有使用者 
use yourDB:切換當前資料庫至yourDB ,如果資料庫不存在,則指向資料庫,但不建立,直到插入資料或建立集合時資料庫才被建立
db.help() :顯示資料庫操作命令

db.dropDatabase():刪除當前指向的資料庫,如果資料庫不存在,則什麼也不做

quit():推出資料庫

3.MongoDB圖形化管理工具

還有:robomongo等

4.MongoDB的欄位型別

常用的幾種資料型別:
Object ID:文件ID
String:字串,最常用,必須是有效的UTF-8
Boolean:儲存一個布林值,true或false
Integer:整數可以是32位或64位,這取決於伺服器
Double:儲存浮點值
Arrays:陣列或列表,多個值儲存到一個鍵
Object:用於嵌入式的文件,即一個值為一個文件
Null:儲存Null值
Timestamp:時間戳
Date:儲存當前日期或時間的UNIX時間格式

object id:
每個文件都有一個屬性,為_id,保證每個文件的唯一性
可以自己去設定_id插入文件
如果沒有提供,那麼MongoDB為每個文件提供了一個獨特的_id,型別為objectID
objectID是一個12位元組的十六進位制數
前4個位元組為當前時間戳
接下來3個位元組的機器ID
接下來的2個位元組中MongoDB的服務程序id
最後3個位元組是簡單的增量值

object id:
每個文件都有一個屬性,為_id,保證每個文件的唯一性
可以自己去設定_id插入文件
如果沒有提供,那麼MongoDB為每個文件提供了一個獨特的_id,型別為objectID
objectID是一個12位元組的十六進位制數
前4個位元組為當前時間戳
接下來3個位元組的機器ID
接下來的2個位元組中MongoDB的服務程序id
最後3個位元組是簡單的增量值

5.MongoDB的基本操作

集合的操作:

集合建立

db.createCollection(name, options)

name是要建立的集合的名稱
options是一個文件,用於指定集合的配置
選項​​引數是可選的,所以只需要到指定的集合名稱。以下是可以使用的選項列表:
例1:不限制集合大小

db.createCollection("stu")

例2:限制集合大小,後面學會插入語句後可以檢視效果
引數capped:預設值為false表示不設定上限,值為true表示設定上限
引數size:當capped值為true時,需要指定此引數,表示上限大小,當文件達到上限時,會將之前的資料覆蓋,單位為位元組

db.createCollection("sub", { capped : true, size : 10 } )


檢視當前資料庫的集合

show collections

刪除集合

db.集合名稱.drop()
基本的增刪改查


插入

db.集合名稱.insert(document)
插入文件時,如果不指定_id引數,MongoDB會為文件分配一個唯一的ObjectId
例1
db.stu.insert({name:'gj',gender:1})
例2
s1={_id:'20160101',name:'hr'}
s1.gender=0
db.stu.insert(s1)

簡單查詢
db.集合名稱.find()


更新
db.集合名稱.update(
   <query>,
   <update>,
   {multi: <boolean>}
)

引數query:查詢條件,類似sql語句update中where部分
引數update:更新操作符,類似sql語句update中set部分
引數multi:可選,預設是false,表示只更新找到的第一條記錄,值為true表示把滿足條件的文件全部更新

例3:全文件更新

db.stu.update({name:'hr'},{name:'mnc'})

例4:指定屬性更新,通過操作符$set
db.stu.insert({name:'hr',gender:0})
db.stu.update({name:'hr'},{$set:{name:'hys'}})

例5:修改多條匹配到的資料
db.stu.update({},{$set:{gender:0}},{multi:true})
儲存
db.集合名稱.save(document)
如果文件的_id已經存在則修改,如果文件的_id不存在則新增

例6
db.stu.save({_id:'20160102','name':'yk',gender:1})

例7
db.stu.save({_id:'20160102','name':'wyk'})


刪除

db.集合名稱.remove(
   <query>,
   {
     justOne: <boolean>
   }
)

引數query:可選,刪除的文件的條件
引數justOne:可選,如果設為true或1,則只刪除一條,預設false,表示刪除多條

例8:只刪除匹配到的第一條

db.stu.remove({gender:0},{justOne:true})

例9:全部刪除
db.stu.remove({})
關於size的示例


例10
建立集合

db.createCollection('sub',{capped:true,size:10})

插入第一條資料庫查詢
db.sub.insert({title:'linux',count:10})
db.sub.find()
插入第二條資料庫查詢
db.sub.insert({title:'web',count:15})
db.sub.find()
插入第三條資料庫查詢
db.sub.insert({title:'sql',count:8})
db.sub.find()
插入第四條資料庫查詢
db.sub.insert({title:'django',count:12})
db.sub.find()
插入第五條資料庫查詢
db.sub.insert({title:'python',count:14})
db.sub.find()


6.MongoDB的查詢方式

基本查詢
方法find():查詢

db.集合名稱.find({條件文件})

方法findOne():查詢,只返回第一個
db.集合名稱.findOne({條件文件})

方法pretty():將結果格式化
db.集合名稱.find({條件文件}).pretty()

比較運算子

等於,預設是等於判斷,沒有運算子
小於$lt
小於或等於$lte
大於$gt
大於或等於$gte
不等於$ne


例1:查詢名稱等於'gj'的學生

db.stu.find({name:'gj'})

例2:查詢年齡大於或等於18的學生
db.stu.find({age:{$gte:18}})

邏輯運算子

查詢時可以有多個條件,多個條件之間需要通過邏輯運算子連線
邏輯與:預設是邏輯與的關係
例3:查詢年齡大於或等於18,並且性別為1的學生
db.stu.find({age:{$gte:18},gender:1})

邏輯或:使用$or
例4:查詢年齡大於18,或性別為0的學生
db.stu.find({$or:[{age:{$gt:18}},{gender:1}]})

and和or一起使用
例5:查詢年齡大於18或性別為0的學生,並且學生的姓名為gj
db.stu.find({$or:[{age:{$gte:18}},{gender:1}],name:'gj'})

範圍運算子

使用"$in","$nin" 判斷是否在某個範圍內
例6:查詢年齡為18、28的學生
db.stu.find({age:{$in:[18,28]}})


支援正則表示式

使用//或$regex編寫正則表示式
例7:查詢姓黃的學生
db.stu.find({name:/^黃/})
db.stu.find({name:{$regex:'^黃'}}})

自定義查詢

使用$where後面寫一個函式,返回滿足條件的資料
例7:查詢年齡大於30的學生
db.stu.find({$where:function(){return this.age>20}})

Limit:

方法limit():用於讀取指定數量的文件
語法:
db.集合名稱.find().limit(NUMBER)

引數NUMBER表示要獲取文件的條數
如果沒有指定引數則顯示集合中的所有文件
例1:查詢2條學生資訊
db.stu.find().limit(2)

skip
方法skip():用於跳過指定數量的文件
語法:
db.集合名稱.find().skip(NUMBER)

引數NUMBER表示跳過的記錄條數,預設值為0
例2:查詢從第3條開始的學生資訊
db.stu.find().skip(2)

一起使用
方法limit()和skip()可以一起使用,不分先後順序

建立資料集

for(i=0;i<15;i++){db.t1.insert({_id:i})}

查詢第5至8條資料
db.stu.find().limit(4).skip(5)


db.stu.find().skip(5).limit(4)

投影


在查詢到的返回結果中,只選擇必要的欄位,而不是選擇一個文件的整個欄位
如:一個文件有5個欄位,需要顯示只有3個,投影其中3個欄位即可
語法:
引數為欄位與值,值為1表示顯示,值為0不顯示

db.集合名稱.find({},{欄位名稱:1,...})

對於需要顯示的欄位,設定為1即可,不設定即為不顯示
特殊:對於_id列預設是顯示的,如果不顯示需要明確設定為0
例1
db.stu.find({},{name:1,gender:1})

例2
db.stu.find({},{_id:0,name:1,gender:1})

排序
方法sort(),用於對結果集進行排序

db.集合名稱.find().sort({欄位:1,...})

引數1為升序排列
引數-1為降序排列

例1:根據性別降序,再根據年齡升序

db.stu.find().sort({gender:-1,age:1})

統計個數


方法count()用於統計結果集中文件條數

db.集合名稱.find({條件}).count()


也可以與為
db.集合名稱.count({條件})

例1:統計男生人數
db.stu.find({gender:1}).count()

例2:統計年齡大於20的男生人數
db.stu.count({age:{$gt:20},gender:1})

消除重複

方法distinct()對資料進行去重

db.集合名稱.distinct('去重欄位',{條件})

例1:查詢年齡大於18的性別(去重)
db.stu.distinct('gender',{age:{$gt:18}})

7.MongoDB高階操作

包括聚合、主從複製、分片、備份與恢復、MR

聚合 aggregate:
聚合(aggregate)主要用於計算資料,類似sql中的sum()、avg()

db.集合名稱.aggregate([{管道:{表示式}}])

管道

管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的輸入
ps ajx | grep mongo


在mongodb中,管道具有同樣的作用,文件處理完畢後,通過管道進行下一次處理

常用管道


$group:將集合中的文件分組,可用於統計結果

$match:過濾資料,只輸出符合條件的文件
$project:修改輸入文件的結構,如重新命名、增加、刪除欄位、建立計算結果
$sort:將輸入文件排序後輸出
$limit:限制聚合管道返回的文件數
$skip:跳過指定數量的文件,並返回餘下的文件
$unwind:將陣列型別的欄位進行拆分

表示式


處理輸入文件並輸出

表示式:'$列名'

常用表示式
$sum:計算總和,$sum:1同count表示計數
$avg:計算平均值
$min:獲取最小值
$max:獲取最大值
$push:在結果文件中插入值到一個數組中
$first:根據資源文件的排序獲取第一個文件資料
$last:根據資源文件的排序獲取最後一個文件資料

$group

將集合中的文件分組,可用於統計結果
_id表示分組的依據,使用某個欄位的格式為'$欄位'
例1:統計男生、女生的總人數

db.stu.aggregate([
    {$group:
        {
            _id:'$gender',
            counter:{$sum:1}
        }
    }
])


Group by null

將集合中所有文件分為一組
例2:求學生總人數、平均年齡
db.stu.aggregate([
    {$group:
        {
            _id:null,
            counter:{$sum:1},
            avgAge:{$avg:'$age'}
        }
    }
])


透視資料


例3:統計學生性別及學生姓名

db.stu.aggregate([
    {$group:
        {
            _id:'$gender',
            name:{$push:'$name'}
        }
    }
])


使用$$ROOT可以將文件內容加入到結果集的陣列中,程式碼如下

db.stu.aggregate([
    {$group:
        {
            _id:'$gender',
            name:{$push:'$$ROOT'}
        }
    }
])

$match:

用於過濾資料,只輸出符合條件的文件
使用MongoDB的標準查詢操作
例1:查詢年齡大於20的學生

db.stu.aggregate([
    {$match:{age:{$gt:20}}}
])


例2:查詢年齡大於20的男生、女生人數
db.stu.aggregate([
    {$match:{age:{$gt:20}}},
    {$group:{_id:'$gender',counter:{$sum:1}}}
])

$project:

修改輸入文件的結構,如重新命名、增加、刪除欄位、建立計算結果
例1:查詢學生的姓名、年齡

db.stu.aggregate([
    {$project:{_id:0,name:1,age:1}}
])


例2:查詢男生、女生人數,輸出人數
db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$project:{_id:0,counter:1}}
])

$sort

將輸入文件排序後輸出
例1:查詢學生資訊,按年齡升序
b.stu.aggregate([{$sort:{age:1}}])
例2:查詢男生、女生人數,按人數降序

db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$sort:{counter:-1}}
])

$limit

限制聚合管道返回的文件數
例1:查詢2條學生資訊

db.stu.aggregate([{$limit:2}])

$skip


跳過指定數量的文件,並返回餘下的文件
例2:查詢從第3條開始的學生資訊

db.stu.aggregate([{$skip:2}])
例3:統計男生、女生人數,按人數升序,取第二條資料
db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$sort:{counter:1}},
    {$skip:1},
    {$limit:1}
])

注意順序:先寫skip,再寫limit

$unwind

將文件中的某一個數組型別欄位拆分成多條,每條包含陣列中的一個值
語法1

對某欄位值進行拆分

db.集合名稱.aggregate([{$unwind:'$欄位名稱'}])

構造資料
db.t2.insert({_id:1,item:'t-shirt',size:['S','M','L']})

查詢
db.t2.aggregate([{$unwind:'$size'}])


語法2


對某欄位值進行拆分
處理空陣列、非陣列、無欄位、null情況

db.inventory.aggregate([{
    $unwind:{
        path:'$欄位名稱',
        preserveNullAndEmptyArrays:<boolean>#防止資料丟失
    }
}])

構造資料
db.t3.insert([
{ "_id" : 1, "item" : "a", "size": [ "S", "M", "L"] },
{ "_id" : 2, "item" : "b", "size" : [ ] },
{ "_id" : 3, "item" : "c", "size": "M" },
{ "_id" : 4, "item" : "d" },
{ "_id" : 5, "item" : "e", "size" : null }
])

使用語法1查詢
db.t3.aggregate([{$unwind:'$size'}])

檢視查詢結果,發現對於空陣列、無欄位、null的文件,都被丟棄了
問:如何能不丟棄呢?
答:使用語法2查詢
db.t3.aggregate([{$unwind:{path:'$sizes',preserveNullAndEmptyArrays:true}}])

8.MongoDB的安全

超級管理員


為了更安全的訪問mongodb,需要訪問者提供使用者名稱和密碼,於是需要在mongodb中建立使用者
採用了角色-使用者-資料庫的安全管理方式
常用系統角色如下:
root:只在admin資料庫中可用,超級賬號,超級許可權
Read:允許使用者讀取指定資料庫
readWrite:允許使用者讀寫指定資料庫
建立超級管理使用者

use admin
db.createUser({
    user:'admin',
    pwd:'123',
    roles:[{role:'root',db:'admin'}]
})

啟用安全認證

修改配置檔案
sudo vi /etc/mongod.conf


啟用身份驗證
注意:keys and values之間一定要加空格, 否則解析會報錯
security:
  authorization: enabled

重啟服務
sudo service mongod stop
sudo service mongod start

終端連線
 mongo -u 'admin' -p '123' --authenticationDatabase 'admin'

普通使用者管理

使用超級管理員登入,然後進入使用者管理操作
檢視當前資料庫的使用者
use test1
show users

建立普通使用者
db.createUser({
    user:'t1',
    pwd:'123',
    roles:[{role:'readWrite',db:'test1'}]
})


終端連線
mongo -u t1 -p 123 --authenticationDatabase test1

切換資料庫,執行命令檢視效果

修改使用者:可以修改pwd、roles屬性

db.updateUser('t1',{pwd:'456'})

9.MongoDB的複製


什麼是複製
複製提供了資料的冗餘備份,並在多個伺服器上儲存資料副本,提高了資料的可用性,並可以保證資料的安全性
複製還允許從硬體故障和服務中斷中恢復資料


為什麼要複製

資料備份
資料災難恢復
讀寫分離
高(24* 7)資料可用性
無宕機維護
副本集對應用程式是透明


複製的工作原理
複製至少需要兩個節點A、B...
A是主節點,負責處理客戶端請求
其餘的都是從節點,負責複製主節點上的資料
節點常見的搭配方式為:一主一從、一主多從
主節點記錄在其上的所有操作,從節點定期輪詢主節點獲取這些操作,然後對自己的資料副本執行這些操作,從而保證從節點的資料與主節點一致
主節點與從節點進行資料互動保障資料的一致性


複製的特點
N 個節點的叢集
任何節點可作為主節點
所有寫入操作都在主節點上
自動故障轉移
自動恢復

實現:

10.mongoDB的備份與恢復

備份

mongodump -h dbhost -d dbname -o dbdirectory

-h:伺服器地址,也可以指定埠號
-d:需要備份的資料庫名稱
-o:備份的資料存放位置,此目錄中存放著備份出來的資料

例1

sudo mkdir test1bak
sudo mongodump -h 192.168.196.128:27017 -d test1 -o ~/Desktop/test1bak

恢復


mongorestore -h dbhost -d dbname --dir dbdirectory

-h:伺服器地址
-d:需要恢復的資料庫例項
--dir:備份資料所在位置

例2

mongorestore -h 192.168.196.128:27017 -d test2 --dir ~/Desktop/test1bak/test1