一、NoSQL概述
NoSQL是Not Only SQL的縮寫,指的是非關系型數(shù)據(jù)庫,與傳統(tǒng)的關系型數(shù)據(jù)庫相對應,主要用于超大規(guī)模數(shù)據(jù)的存儲。
與RDBMS相比,具有如下特點:
- 沒有聲明性查詢語言
- 沒有預定義模式
- 鍵值對存儲
- 最終一致性
- 非結構化和不可預知的數(shù)據(jù)
- CAP定理
- 高性能和可伸縮性
優(yōu)點:高可擴展性;分布式計算;低成本;半結構化數(shù)據(jù);關系簡單。
缺點:沒有標準化;查詢功能有限;最終一致性沒有ACID直觀。
二、MongoDB概述
MongoDB是一個基于分布式文件存儲的開源數(shù)據(jù)庫系統(tǒng),為Web應用提供可擴展的高性能數(shù)據(jù)存儲解決方案。將數(shù)據(jù)存儲為一個文檔,數(shù)據(jù)結構由鍵值對組成。存儲的數(shù)據(jù)與應用的數(shù)據(jù),在格式上(JSON)高度一致。
主要特點:
- 面向文檔存儲,操作簡單
- 可以設置任何屬性的索引
- 支持豐富的查詢表達式
- 允許在服務端執(zhí)行腳本
- 支持各種編程語言
- 具有更高的擴展性
- 可以將負載分布在各個節(jié)點
三、主要概念
1、數(shù)據(jù)庫database
與RDBMS的概念相同。MongoDB的默認數(shù)據(jù)庫為“db”,存儲在data目錄中。不同的數(shù)據(jù)庫放置在不同的文件中。
數(shù)據(jù)庫名稱的限制:
- 不能是空字符串
- 不能包含空格、“.”、“/”、“\”、“$”、空字符等
- 應該全部小寫
- 最長64個字節(jié)
保留的數(shù)據(jù)庫名稱:
- admin,相當于一個root數(shù)據(jù)庫,如果將用戶添加到該數(shù)據(jù)庫,那么該用戶將自動獲得所有數(shù)據(jù)庫的權限
- local,這個數(shù)據(jù)庫不會被復制,可以用來存儲僅限于本地單個服務器的任意集合
- config,當Mongo用于分片設置時,該數(shù)據(jù)庫在內(nèi)部使用,用來保存分片的相關信息
2、集合collection
相當于RDBMS中“表”的概念。集合沒有固定的結構,可以插入不同格式和類型的數(shù)據(jù)。數(shù)據(jù)庫的信息存儲在dbname.system命名空間下的特殊集合中。
集合名稱的限制:
- 不能是空字符串
- 不能包含空字符,空字符表示集合名的結尾
- 不能以system開頭,屬于系統(tǒng)保留的前綴
- 不能包含保留字符
3、文檔document
相當于RDBMS中“行”的概念。MongoDB的文檔不需要設置相同的字段,并且相同字段不需要相同的數(shù)據(jù)類型。文檔的數(shù)據(jù)結構采用BSON格式,和JSON基本相同,BSON是一種類json的二進制形式的存儲格式。
使用文檔時需要注意:
- 文檔中的鍵值對是有序的
- 文檔中的值可以是任意數(shù)據(jù)類型
- 區(qū)分類型和大小寫
- 不能有重復的鍵
- 文檔的鍵是字符串
4、字段field
相當于RDBMS中“列”的概念。
字段的常用類型:
- String,字符串類型,在MongoDB中,UTF-8才是合法編碼
- Integer,整形數(shù)值
- Boolean,布爾值
- Double,雙精度浮點值
- Min/Max keys,將一個值與BSON(二進制的JSON)元素的最低值/最高值相比較
- Arrays,將數(shù)組或列表或多個值存儲為一個鍵
- Timestamp,時間戳,記錄文檔修改或添加的具體時間
- Object,用于內(nèi)嵌文檔
- Null,用于創(chuàng)建空值
- Symbol,符號,基本等同于字符串類型
- Date,日期時間
- Object ID,用于創(chuàng)建文檔的ID
- Binary Data,用于存儲二進制數(shù)據(jù)
- Code,代碼類型,用于在文檔中存儲JavaScript代碼
- Regular expression,正則表達式類型,用于存儲正則表達式
5、索引index
與RDBMS的概念相同。
6、主鍵primary key
自動將_id字段設置為主鍵。
7、表連接
不支持表連接,但可以通過嵌入文檔的方式實現(xiàn)。
四、用法
1、安裝
從官網(wǎng)下載并直接安裝,設置path環(huán)境變量。
2、啟動
直接啟動:
mongod
指定配置文件啟動:
mongod --config /etc/mongodb.conf
3、操作數(shù)據(jù)庫
創(chuàng)建數(shù)據(jù)庫:
use DATABASE_NAME
如果數(shù)據(jù)庫不存在,則創(chuàng)建數(shù)據(jù)庫,否則切換到指定的數(shù)據(jù)庫。
查看當前數(shù)據(jù)庫:
db
查看所有數(shù)據(jù)庫:
show dbs
刪除當前數(shù)據(jù)庫:
db.dropDatabase()
在刪除之前應該使用db命令查看當前數(shù)據(jù)庫名,或者使用use命令切換到要刪除的數(shù)據(jù)庫。
刪除集合:
db.collection.drop()
4、操作文檔
插入:
db.COLLECTION_NAME.insert(document)
如果集合不存在,MongoDB會自動創(chuàng)建該集合并插入文檔。如果不指定_id字段,save方法與insert方法類似。如果指定_id字段,save方法會更新該_id的數(shù)據(jù)。
更新:
db.COLLECTION_NAME.update(query, update, {upsert:boolean, multi:boolean, writeConcern:document})
- query,更新的查詢條件,相對于sql的where語句
- update,更新的對象和操作符,相對于sql的set語句
- upsert,可選,如果要更新的記錄不存在,是否插入新記錄,true為插入,默認false為不插入
- multi,可選,默認false為只更新第一條記錄,如果為true,則全部更新
- writeConcern,可選,表示拋出異常的級別
通過傳入的文檔替換已有的文檔:
db.COLLECTION_NAME.save(document, {writeConcern:document})
刪除:
db.COLLECTION_NAME.remove(query, {justOne:boolean, writeConcern:document})
- query,可選,要刪除的文檔的滿足條件
- justOne,可選,如果為true,則只刪除一個文檔
- writeConcern,可選,表示拋出異常的級別
如果不包含任何參數(shù),則刪除集合中的所有文檔。建議在執(zhí)行remove操作之前,先執(zhí)行find命令來判斷執(zhí)行條件是否正確。
查詢:
db.COLLECTION_NAME.find()
如果希望格式化查詢的結果,可以使用pretty方法:
db.COLLECTION_NAME.find().pretty()
如果希望只返回一個文檔:
db.COLLECTION_NAME.findOne()
在find方法中,傳入多個鍵值對,每個鍵值對之間以逗號分隔,等價于SQL中的and條件:
db.COLLECTION_NAME.find({key1:value1, key2:value2})
在find方法中,使用關鍵字$or,等價于SQL中的or條件:
db.COLLECTION_NAME.find({$or:[{key1:value1, key2:value2}]})
在MongoDB中,有四種條件操作符,分別是$gt、$lt、$gte、$lte,對應SQL中的大于、小于、大于等于和小于等于。
db.COLLECTION_NAME.find({key: {$gt : value}})
還有一個條件操作符$type,用來判斷字段的類型:
db.COLLECTION_NAME.find({key: {$type : typeid}})
使用limit方法,指定要讀取的記錄數(shù)量:
db.COLLECTION_NAME.find().limit(NUMBER)
使用skip方法,跳過指定數(shù)量的記錄,參數(shù)默認為0:
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
使用sort方法,指定排序的字段,參數(shù)為1表示升序,-1表示降序,默認按照升序排列:
db.COLLECTION_NAME.find().sort({KEY:1})
使用aggregate方法,處理數(shù)據(jù)并返回計算后的數(shù)據(jù)結果:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
聚合操作包括:
- $sum,計算求和
- $avg,計算平均值
- $min,獲取最小值
- $max,獲取最大值
- $push,插入值到一個數(shù)組中
- $addToSet,插入值到一個數(shù)組中,但不創(chuàng)建副本
- $first,根據(jù)排序獲取第一個文檔數(shù)據(jù)
- $last,根據(jù)排序獲取最后一個文檔數(shù)據(jù)
在MongoDB中,可以使用聚合管道,將文檔在一個管道處理完畢之后把結果傳遞給下一個管道處理。
常用的管道操作:
- $project,修改輸入文檔的結構,可以用來重命名、增加或刪除字段,也可以用來創(chuàng)建計算結果以及嵌套文檔
- $match,用于過濾數(shù)據(jù),只輸出符合條件的文檔
- $limit,用來限制聚合管道返回的文檔數(shù)
- $skip,在聚合管道中跳過指定數(shù)量的文檔
- $unwind,將文檔中的某一個數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個值
- $group,將集合中的文檔分組,用于統(tǒng)計結果
- $sort,將輸入文檔進行排序之后輸出
- $geoNear,輸出接近某一地理位置的有序文檔
索引是特殊的數(shù)據(jù)結構,存儲在一個易于遍歷讀取的數(shù)據(jù)集合中,是對數(shù)據(jù)庫表中的若干字段的值進行排序的一種結構。MongoDB還提供多個可選參數(shù),用來限定索引的規(guī)則。
創(chuàng)建索引:
db.COLLECTION_NAME.ensureIndex({KEY:1})
5、數(shù)據(jù)庫的備份和恢復
復制:將數(shù)據(jù)同步在多個服務器的過程。提供了數(shù)據(jù)的冗余備份,并在多個服務器上存儲數(shù)據(jù)副本。允許從硬件故障和服務中斷中恢復數(shù)據(jù)。復制至少需要兩個節(jié)點,其中一個是主節(jié)點,負責處理客戶端請求,其余都是從節(jié)點,負責復制主節(jié)點的數(shù)據(jù)。
分片:當存儲海量數(shù)據(jù)時,一臺機器不足以存儲數(shù)據(jù),也不足以提供可接受的讀寫量??梢酝ㄟ^在多臺機器上分割數(shù)據(jù),使得數(shù)據(jù)庫系統(tǒng)能夠存儲和處理更多的數(shù)據(jù)。Shard用于存儲實際的數(shù)據(jù)塊,實際使用中一個shard server可以由幾臺機器組成。Config server存儲整個ClusterMetadata,其中包括chunk信息。Query routers前端路由,客戶端由此接入。
備份:在MongoDB中,可以使用mongodump命令來備份數(shù)據(jù),該命令可以導出所有數(shù)據(jù)到指定目錄。
mongodump -h dbhost -d dbname -o dbdirectory
恢復:在MongoDB中,可以使用mongorestore命令來恢復備份的數(shù)據(jù)。
mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
6、數(shù)據(jù)庫的監(jiān)控
在安裝部署并啟動MongoDB服務后,必須了解運行情況,并查看其性能。
mongostat是MongoDB自帶的狀態(tài)檢測工具。mongotop用來跟蹤一個MongoDB實例,查看讀寫所花費的時間。這兩個工具都位于MongoDB的安裝目錄的bin目錄下。