Mongodb 入門學習筆記
阿新 • • 發佈:2018-11-19
- NoSql簡介
- Not only sql,非關係型資料庫,用於超大規模的資料儲存
- 優點
- 高可擴充套件性
- 分散式計算
- 低成本
- 架構的靈活性,半結構化資料
- 沒有複雜的關係
- 缺點
- 沒有標準化
- 有限的查詢功能
- 最終一致不是直觀的程式
- 優點
- 關係型資料庫的ACID
- 分散式系統
- 優點
- 缺點
- CAP定理
- 一個分散式系統不可能同時滿足以下三個特點
- 一致性(Consistency) (所有節點在同一時間具有相同的資料)
- 可用性(Availability) (保證每個請求不管成功或者失敗都有響應)
- 分隔容忍(Partition tolerance) (系統中任意資訊的丟失或失敗不會影響系統的繼續運作)
- 參考文章
- BASE理論
- 對可用性及一致性的弱要求原則
- Basically Available 基本可用
- Soft-state 軟狀態 無連線的(分散式不同節點副本的同步延時)
- Eventually Consistent 最終一致性
- Not only sql,非關係型資料庫,用於超大規模的資料儲存
- Mongodb簡介
- 面向文件儲存
- JSON
- Mongodb概念解析
- 文件,集合,資料庫
sql術語 | monogdb術語 | 解釋 |
---|---|---|
database | database | 資料庫 |
table | collection | 資料庫表/集合 |
row | docunment | 資料庫行/文件 |
column | filed | 列/欄位 |
index | index | 索引 |
table joins | 資料庫表連線 | |
primary key | primary key | 自增主鍵 |
- 資料庫
- show dbs #檢視所有資料庫
- use test #切換到test資料庫
- 特殊資料庫
- admin
- 從許可權的角度來看,這是"root"資料庫。要是將一個使用者新增到這個資料庫,這個使用者自動繼承所有資料庫的許可權。一些特定的伺服器端命令也只能從這個資料庫執行,比如列出所有的資料庫或者關閉伺服器。
- config
- 當Mongo用於分片設定時,config資料庫在內部使用,用於儲存分片的相關資訊
- local
- 這個資料永遠不會被複制,可以用來儲存限於本地單臺伺服器的任意集合
- admin
- 文件
- key-value鍵值對
- 例如 {“site”:“www.runoob.com”, “name”:“菜鳥教程”}
- 集合
- 文件組
- capped collections 固定大小的collection
- 高效能
- 自動維護物件插入順序
- 儲存空間是提前分配的
- 元資料
- 資料庫的資訊儲存在
- dbname.system.*
- 資料庫的資訊儲存在
- Mongodb資料型別
- String
- Integer
- Boolean
- Double
- Min/Max keys 將值與BSON的最高低值進行比較
- Arrays
- TimeStamp 時間戳。記錄文件修改或新增的具體時間
- Object 用於內嵌文件
- Null
- Symbol 符號
- Date
- Object ID 物件Id 用於建立文件的ID
- Binary Data
- Code 程式碼型別
- Regular expression 用於儲存正則表示式
- 操作資料庫
- 刪除集合
- db.coll_name.drop()
- 檢視集合
- show collections
- 刪除資料庫
- db.dropDatabase()
- 插入文件
- db.COLLECTION_NAME.insert(document)
- db.col.save(document) 也可以用於更新
- document=({title: ‘MongoDB 教程’,
description: ‘MongoDB 是一個 Nosql 資料庫’,
by: ‘Mongodb中文網’,
url: ‘http://www.mongodb.org.cn’,
tags: [‘mongodb’, ‘database’, ‘NoSQL’],
likes: 100
});
- 更新文件
- 更新已存在的文件
- db.collection.update(
query,
update,
{
upsert: ,
multi: ,
writeConcern:
}) - query : update的查詢條件,類似sql update查詢內where後面的。
- update : update的物件和一些更新的操作符(如 inc…)等,也可以理解為sql update查詢內set後面的
- upsert : 可選,這個引數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,預設是false,不插入。
- multi : 可選,mongodb 預設是false,只更新找到的第一條記錄,如果這個引數為true,就把按條件查出來多條記錄全部更新。
- writeConcern :可選,丟擲異常的級別。
- $gt 大於
- $lt 小於
- 刪除文件
- db.collectionName.remove(
- query,
{
justOne: ,
writeConcern:
}) - query :(可選)刪除的文件的條件。
- justOne : (可選)如果設為 true 或 1,則只刪除一個文件。
- writeConcern :(可選)丟擲異常的級別
- MongoDB 查詢文件
- db.col.find()
- db.col.find().pretty() #易讀
- Mongodb與RDBMS比較
- 等於
- db.col.find({“by”:“菜鳥教程”}).pretty()
- where by = ‘菜鳥教程’
- 不等於
- db.col.find({“likes”:{$ne:50}}).pretty()
- where likes != 50
- 大於
- $gt
- 小於
- $lt
- 大於等於
- $gte
- 小於等於
- $lte
- 等於
- AND
- find()內傳入多個key ,逗號隔開
- db.col.find({key1:value1, key2:value2}).pretty()
- OR
- $or
- db.col.find({$or: [{key1: value1}, {key2:value2}]}).pretty()
- AND OR 聯合使用
- db.col.find({“likes”: {$gt:50}, $or: [{“by”: “Mongodb中文網”},{“title”: “MongoDB 教程”}]}).pretty()
- $type 操作符
- 於BSON型別來檢索集合中匹配的資料型別,並返回結果
- db.col.find({“title” : {$type : 2}})
- Limit與Skip方法
- db.COLLECTION_NAME.find().limit(NUMBER)
- db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER) #跳過指定數量的資料
- 排序
- db.COLLECTION_NAME.find().sort({KEY:1}) # 1升序 -1降序
- 如果沒有指定sort()方法的排序方式,預設按照文件的升序排列
- 索引
- 索引儲存在一個易於遍歷讀取的資料集合中,索引是對資料庫表中一列或多列的值進行排序的一種結構
- 建立索引
- ensureIndex()
- db.col.ensureIndex({“title”:1}) # 1升序 -1降序
- 刪除集合
- 聚合
- Mongodb聚合
- 用於處理資料並返回結果
- db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
- 例子 db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {$sum : 1}}}])
- 常見例子
- 管道
- linux中 一般用於將當前命令的輸出結果作為下一個命令的引數
- MongoDB的聚合管道將MongoDB文件在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操作是可以重複的
- 表示式
- 處理輸入文件並輸出
- 常見操作
- $project: 修改輸入文件的結構。可以用來重新命名、增加或刪除域,也可以用於建立計算結果以及巢狀文件
-
match使用MongoDB的標準查詢操作。
- db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
- db.articles.aggregate( [
- $limit:用來限制MongoDB聚合管道返回的文件數。
- $skip:在聚合管道中跳過指定數量的文件,並返回餘下的文件。
- db.article.aggregate({ $skip : 5 });
- $unwind:將文件中的某一個數組型別欄位拆分成多條,每條包含陣列中的一個值。
- $group:將集合中的文件分組,可用於統計結果。
- $sort:將輸入文件排序後輸出。
- $geoNear:輸出接近某一地理位置的有序文件
- Mongodb複製 副本集
- 將資料同步到多個伺服器的過程
- 什麼是複製
- 保障資料的安全性
- 資料高可用性 (24*7)
- 災難恢復
- 無需停機維護(如備份,重建索引,壓縮)
- 分散式讀取資料
- 原理
- 一主一從、一主多從
- 主節點記錄在其上的所有操作 oplog,從節點定期輪詢主節點獲取這些操作,然後對自己的資料副本執行這些操作,從而保證從節點的資料與主節點一致
- 副本集特徵
- N個點的叢集
- 任何節點可作為主節點
- 所有寫入都在主節點
- 自動故障轉移
- 自動恢復
- 實踐
- MongoDB 分片
- 在多臺機器上分割資料,使得資料庫系統能儲存和處理更多的資料
- 原因
- 複製所有的寫入操作到主節點
- 延遲的敏感資料會在主節點查詢
- 單個副本集限制在12個節點
- 當請求量巨大時會出現記憶體不足
- 本地磁碟不足
- 垂直擴充套件價格昂貴
- 元件
- Shard
- 用於儲存實際的資料塊,實際生產環境中一個shard server角色可由幾臺機器組個一個relica set承擔,防止主機單點故障
- Config Server
- mongod例項,儲存了整個 ClusterMetadata,其中包括 chunk資訊
- Query Routers
- 前端路由,客戶端由此接入,且讓整個叢集看上去像單一資料庫,前端應用可以透明使用
- Shard
- Mongodb聚合
- 資料備份
- mongodump -h dbhost -d dbname -o dbdirectory
- 資料恢復
- mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
- 監控
- mongostat,當前執行狀態
- mongotop,檢視讀寫花費的時間
- mongotop 10 10秒鐘讀取一次
- –locks 報告每個資料庫的鎖的使用中 3.0後已取消
- MongoDB 關係
- 1:1
- 1:N
- N:1
- N:N
- 嵌入式關係
- {
“_id”:ObjectId(“52ffc33cd85242f436000001”),
“contact”: “987654321”,
“dob”: “01-01-1991”,
“name”: “Tom Benzamin”,
“address”: [
{
“building”: “22 A, Indiana Apt”,
“pincode”: 123456,
“city”: “Los Angeles”,
“state”: “California”
},
{
“building”: “170 A, Acropolis Apt”,
“pincode”: 456789,
“city”: “Chicago”,
“state”: “Illinois”
}]
}
- {
- 引用式關係
- {
“_id”:ObjectId(“52ffc33cd85242f436000001”),
“contact”: “987654321”,
“dob”: “01-01-1991”,
“name”: “Tom Benzamin”,
“address_ids”: [
ObjectId(“52ffc4a5d85242602e000000”),
ObjectId(“52ffc4a5d85242602e000001”)
]
}
- {
- 資料庫引用
- 手動引用
- DBRefs
- 一個文件從多個集合引用文件,我們應該使用 DBRefs
- { $ref(集合名稱) : , $id(引用的ID) : , $db(資料庫的名稱) : }
- 覆蓋索引查詢
- 所有的查詢欄位是索引的一部分
- 所有的查詢返回欄位在同一個索引中
- 例子
- db.users.insert({“contact”: “987654321”, “dob”: “01-01-1991”, “gender”: “M”, “name”: “Tom Benzamin”, “user_name”: “tombenzamin”})
- db.users.ensureIndex({gender:1,user_name:1}) //createIndex()
- //覆蓋 db.users.find({gender:“M”},{user_name:1,_id:0})
- //不覆蓋 db.users.find({gender:“M”},{user_name:1})
- 注意以下不能使用覆蓋索引
- 所有索引欄位是一個子文件
- 所有索引欄位是一個數組
- 查詢索引
- db.users.getIndexes()
- 查詢分析
- explain()
- indexOnly true表示使用了索引
- cursor
- hint()
- 強迫使用一個指定索引
- explain()
- 原子操作
- mongodb不支援事務,要麼儲存要麼不儲存不會出現不完整的情況。
- db.collection.findAndModify()
- $set
- $unset
- $inc
- $push
- $pushAll
- $pull
- $addToSet
- $pop
- $rename
- $bit
- 高階索引
- 索引陣列欄位
- db.users.ensureIndex({“tags”:1})
- 索引子文件欄位
- db.users.ensureIndex({“address.city”:1,“address.state”:1,“address.pincode”:1})
- 索引陣列欄位
- 索引限制
- 額外開銷
- 記憶體使用
- 查詢限制
- 索引鍵限制
- 插入文件超過索引鍵限制
- 最大範圍
- 集合中索引不能超過64個
- 索引名的長度不能超過125個字元
- 一個複合索引最多可以有31個欄位
- ObjectId
- 一個12位元組 BSON 型別資料結構
- 前4個位元組表示時間戳
- 接下來的3個位元組是機器標識碼
- 緊接的兩個位元組由程序id組成(PID)
- 最後三個位元組是隨機數
- 建立新的id
- newObjectId = ObjectId()
- ObjectId(“5be3e06a0d79133288002c7c”).getTimestamp() 獲取文件建立時間
- 轉字串
- new ObjectId().str
- 一個12位元組 BSON 型別資料結構
- Map Reduce
-
Map-Reduce是一種計算模型,簡單的說就是將大批量的工作(資料)分解(MAP)執行,然後再將結果合併成最終結果(REDUCE)
``` db.posts.mapReduce( function() { emit(this.user_name,1); }, function(key, values) {return Array.sum(values)}, { query:{status:"active"}, out:"post_total" } ) ```
-
- 全文檢索
- 對每一個詞建立索引
- v2.6以後預設開啟
- db.p.ensureIndex({post_text: “text”})
- db.p.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: text:{search:“mongodb.org.cn”}})
- 刪除
- db.p.dropIndex(“post_text_text”)
- 正則表示式
- $regex
- GridFS
- 用於儲存和恢復那些超過16M(BSON檔案限制)的檔案(如:圖片、音訊、視訊等
- mongofiles.exe -d gridfs put song.mp3
- db.fs.files.find() 查詢文件
- db.fs.chunks.find({files_id:ObjectId(‘534a811bf8b4aa4d33fdf94d’)}) 根據文件id查詢chunks
- 固定集合 Capped Collections
- db.createCollection(“cappedLogCollection”,{capped:true,size:10000})
- db.cappedLogCollection.isCapped() 判斷是否固定
- db.runCommand({“convertToCapped”:“posts”,size:10000}) 已存在post集合轉為固定集合
- db.createCollection(“cappedLogCollection”,{capped:true,size:10000}) 建立固定集合
- 查詢安裝插入順序返回
- 特點
- 在32位機子上一個cappped collection的最大值約為482.5M,64位上只受系統檔案大小的限制
- 對固定集合進行插入速度極快
- 按照插入順序的查詢輸出速度極快
- 能夠在插入最新資料時,淘汰最早的資料
- 用途
- 儲存日誌資訊
- 快取一些少量的文件
- MongoDB 自動增長
- db.user.save({
uid: db.ids .findAndModify({
update:{$inc:{‘id’:1}},
query:{“name”:“user”},
new:true}).id, //讓db.ids集合中的name="user"文件的id值加1並返回充當自增id
username: “dotcoo”,
password:“dotcoo”,
info:"http://www.dotcoo.com/ "});
- db.user.save({
- 本文所有筆記均來自於Mongodb教程