在介紹 MongoDB 之前,我先介紹一下業務開發的時候遇到的痛點,以便大家對它有一個更加清晰的認識!
最近在用資料庫儲存資料的時候發現這麼一個坑,例如從訊息佇列中監聽訊息的時候,原來的做法是將監聽的訊息資料儲存在資料庫,以便好對異常訊息資料進行追溯,訊息內容使用text
型別儲存,起初因為資料內容很短,沒啥毛病,但是當隨著業務的擴充套件,收到的訊息內容越來越長,最後發現資料庫中的text
欄位型別無法很好的支援查詢,於是在這個時候,就開始考慮採用更加合適的資料庫來儲存這種訊息資料!
在經過一番討論之後,對於這種 json 型別的訊息資料的儲存,大家一致認為採用 MongoDB 是最佳的選擇!
據官方介紹,MongoDB 是一個介於關聯式資料庫和非關聯式資料庫之間的產品,是非關聯式資料庫當中功能最豐富、最像關聯式資料庫的一款高效能的 NoSQL 資料庫。
MongoDB 將資料儲存為一個檔案,資料結構由鍵值(key=>value
)對組成。
其中的檔案類似於 JSON 物件。欄位值可以包含其他檔案、陣列及檔案陣列,資料結構的支援非常靈活!
的確,在使用的過程當中,正如所介紹的,資料的儲存和查詢,效能極快,而且很好的滿足我們的需求!
話不多說,下面我們就一起來了解一下,這款資料庫應該如何使用!
在學習它之前,我們需要先搭建好環境,MongoDB 的安裝也非常簡單!
如果你是 Windows 平臺,MongoDB 提供了可用於 32 位和 64 位系統的預編譯二進位制,安裝基本是傻瓜式的操作,登入 MongoDB 官網並且下載安裝包,然後一步一步的操作即可!
生產環境基本都是 Linux 平臺,為了和生產保持一致,小編採用的伺服器是CentOS7
,安裝過程也比較簡單!
sudo vim /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
sudo yum install -y mongodb-org
mongod.conf
允許遠端連線#編輯mongod.conf
vim /etc/mongod.conf
#將net:bindIp: 127.0.0.1 改為 0.0.0.0
net:
bindIp:0.0.0.0
#開啟服務
systemctl start mongod
#其他服務
#關閉服務
systemctl stop mongod
#重啟服務
systemctl restart mongod
#開機自啟
systemctl enable mongod
至此,環境設定已經完成!
MongoDB 的資料操作,是開發人員接觸最頻繁的部分,第一次使用的時候,你會發現它和我們傳統使用的 sql 指令碼命令完全不同,但是又類似,下面我們就一起來深入的瞭解下!
進入 MongoDB 服務很簡單,輸入如下命令即可進入!
mongo
例如,在CentOS
裡面輸入命令之後,進入的服務介面如下:
MongoDB 建立資料庫的語法格式如下:
use DATABASE_NAME
如果資料庫不存在,則建立資料庫,否則切換到指定資料庫。
輸入如下命令,可以查詢資料庫列表
#查詢資料庫列表
show dbs
#命令輸出結果:
admin
config
local
可以看到,當前 MongoDB 有三個資料庫!
輸入如下命令,可以切換到admin
資料庫
use admin
輸入db
命令,還可以查詢當前資料庫
db
預設的情況下,是沒有使用者的,也無法運算元據庫,因此我們需要建立一個使用者,同時給他分配許可權!
建立一個使用者、密碼都是admin
的使用者,同時給這個使用者分配userAdminAnyDatabase
角色,指定的資料庫為admin
!
#建立一個admin使用者
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
其中欄位含義如下:
userAdminAnyDatabase
,只在 admin 資料庫中可用。角色在 MongoDB 中,代表著某個使用者是否有許可權存取資料庫或者運算元據庫,理解這點非常重要!
MongoDB 角色定義如下:
角色型別 | 名稱 | 描述 |
---|---|---|
admin資料庫角色 | readAnyDatabase | 只在admin資料庫中可用,賦予使用者所有資料庫的讀許可權 |
admin資料庫角色 | readWriteAnyDatabase | 只在admin資料庫中可用,賦予使用者所有資料庫的讀寫許可權 |
admin資料庫角色 | userAdminAnyDatabase | 只在admin資料庫中可用,賦予使用者所有資料庫的userAdmin許可權 |
admin資料庫角色 | dbAdminAnyDatabase | 只在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin許可權 |
admin資料庫角色 | clusterAdmin | 只在admin資料庫中可用,賦予使用者所有分片和複製集相關函數的管理許可權 |
admin資料庫角色 | root | 只在admin資料庫中可用,超級賬號,超級許可權 |
資料庫管理角色 | dbAdmin | 允許使用者在指定資料庫中執行管理函數,如索引建立、刪除,檢視統計或存取system.profile |
資料庫管理角色 | userAdmin | 允許使用者向system.users集合寫入,可以在指定資料庫裡建立、刪除和管理使用者 |
資料庫使用者角色 | read | 允許使用者讀取指定資料庫 |
資料庫使用者角色 | readWrite | 允許使用者讀寫指定資料庫 |
如果你想建立一個不受存取限制的超級使用者,賦予root
角色即可!
#建立超級使用者
db.createUser(
{
user:"root",
pwd:"root",
roles:["root"]
}
)
如果你想建立一個業務資料庫普通使用者,例如只能存取test_db
資料庫,並且只負責資料的増查改刪。
# 建立或者切換資料庫到test_db
use test_db
# 建立一個test使用者,並且只能存取test_db,對錶只有讀寫許可權
db.createUser(
{
user: "test",
pwd: "test",
roles: [ { role: "readWrite", db: "test_db" } ]
})
對於剛剛建立的使用者,我們怎麼驗證它是否能正常登入呢?命令也很簡單!
db.auth("test","test")
如果返回是1
表示鑑權正常!
查詢建立的使用者,命令也很簡單!
# 檢視建立的使用者
show users
有些時候,我們會忘記密碼,可通過如下方式進行修改!
#修改使用者密碼
db.changeUserPassword("username", "xxxxx")
如果某個使用者需要停用,可通過如下方式進行刪除
#切換指定資料庫
use test_db
#刪除使用者
db.dropUser('test')
如果某個資料庫需要停用,可通過如下方式進行刪除(只有超級管理員有許可權刪除)
#切換指定資料庫
use test_db
#刪除資料庫
db.dropDatabase()
MongoDB 並無表這個概念,而對應的定義叫:集合,我們在關係型資料庫中看到的表資料,在 MongoDB 中被定義為:檔案,MongoDB 也被很多人成為檔案資料庫!
在關係型資料庫中,表資料是一行一行的儲存,但是在 MongoDB 中,可能不是這樣,如果你儲存的 json 非常複雜,巢狀很深,那麼在 MongoDB 中儲存的行數,可能非常深,儲存的時候類似我們在頁面看到的父子表結構!
MongoDB 中使用 createCollection() 方法來建立集合。
語法格式:
db.createCollection(name, options)
引數說明:
例如,在 test_db 資料庫中建立 tb_user 集合:
# 切換到test_db資料庫
use test_db
# 建立 tb_user 集合
db.createCollection("tb_user")
#輸出結果
{ "ok" : 1 }
如果要檢視已有的集合,可以使用show collections
命令!
show collections
下面是帶有幾個關鍵引數的createCollection()
的用法,下面命令表示:建立固定集合tb_user
,整個集合空間大小6142800
KB, 檔案最大個數為10000
個
db.createCollection("tb_user", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
在 MongoDB 中,很多時候不需要手動建立集合。當你插入一個檔案時,MongoDB 會自動建立集合!
# 向集合tb_user 插入一條檔案資料
db.tb_user.insert({"name" : "張三"})
#查詢集合
show collections
# 輸出結果
tb_user
MongoDB 中使用 drop() 方法來刪除集合。
語法格式:
db.collection.drop()
例如,刪除在 test_db 資料庫中 tb_user 集合:
# 切換到test_db資料庫
use test_db
# 建立 tb_user 集合
db.tb_user.drop()
#輸出結果
true
建立檔案,類似我們在關係型資料庫中,將資料插入到資料庫,操作也很簡單!
MongoDB 使用 insert()
或 save()
方法向集合中插入檔案。
語法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
save()
:如果_id
主鍵存在則更新資料,如果不存在就插入資料。insert()
:若插入的資料主鍵已經存在,則會拋異常,提示主鍵重複,不儲存當前資料。例如,在test_db
資料庫的tb_user
集合中,插入一條資料
db.tb_user.insert(
{
name:"張三",
age:18,
gender:"男",
tags: ['宅男', '技術控', '脫髮嚴重']
})
如果該集合不在該資料庫中, MongoDB 會自動建立該集合並插入檔案。
檢視已插入檔案,命令如下:
#查詢tb_user集合中的資料
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "張三", "age" : 18, "gender" : "男", "tags" : [ "宅男", "技術控", "脫髮嚴重" ] }
當然,你還可以通過save()
命令進行插入,如果不指定_id
欄位 save()
方法類似於 insert()
方法。如果指定 _id
欄位,則會更新該 _id
的資料。
例如,將張三
年齡更新到30
歲!
db.tb_user.save(
{
_id: ObjectId("6022310f6b5e964b0a5916e6"),
name:"張三",
age:30,
gender:"男",
tags: ['宅男', '技術控', '脫髮嚴重']
})
檢視檔案
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "張三", "age" : 30, "gender" : "男", "tags" : [ "宅男", "技術控", "脫髮嚴重" ] }
MongoDB 提供了 update()
和 save()
方法來更新集合中的檔案。
語法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
例如,將張三
年齡更新到22
歲!
db.tb_user.update({'name':'張三'},{$set:{'age':22}})
查詢已更新的資料
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("602235216b5e964b0a5916e8"), "name" : "張三", "age" : 22, "gender" : "男", "tags" : [ "宅男", "技術控", "脫髮嚴重" ] }
以上語句只會修改第一條發現的檔案,如果你要修改多條相同的檔案,則需要設定multi
引數為true
。
db.tb_user.update({'name':'張三'},{$set:{'age':22}},{multi:true})
MongoDB 中的remove()
函數是用來移除集合中的資料
語法格式如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
例如,刪除姓名為張三
的使用者
db.tb_user.remove({'name':'張三'})
查詢資料是否被刪除
db.col.find()
#結果為空
MongoDB 查詢檔案使用 find() 方法。
語法格式如下:
db.collection.find(query, projection)
如果你需要以易讀的方式來讀取資料,可以使用 pretty() 方法,語法格式如下:
db.col.find().pretty()
首先我們插入幾條資料,插入結果如下:
例如,查詢一個性別為男
的使用者資訊
#單個條件查詢,類似 sql語句中的 gender = '男'
db.tb_user.find({"gender":"男"})
查詢一個性別為男
,姓名為張三
的使用者
#多條件查詢,類似 sql語句中的 gender = '男' and name = '李四'
db.tb_user.find({"gender":"男","name":"李四"})
查詢一個性別為男
或者 姓名為張三
的使用者
#多條件查詢,類似 sql語句中的 gender = '男' or name = '李四'
db.tb_user.find({$or:[{"gender":"男"},{"name": "李四"}]})
查詢一個性別為男
或者 姓名為張三
,同時年齡大於30
的使用者
#多條件查詢,類似 sql語句中的 age > 30 and ( gender = '男' or name = '李四')
db.tb_user.find({"age": {$gt:30}, $or:[{"gender":"男"},{"name": "李四"}]})
如果需要分頁查詢集合資料,可以使用limit()
和skip()
函數,其中limit()
表示讀幾條資料,skip()
表示從第幾條資料開始。
#從集合中的第三行資料開始,讀2條資料返回
db.tb_user.find({}).limit(2).skip(3)
和關係型資料庫一樣,MongoDB 可以使用sort()
方法進行排序,通過引數指定排序的欄位,並使用 1
和 -1
來指定排序的方式,其中 1
為升序排列,而 -1
是用於降序排列。
例如,查詢tb_user
檔案,按照age
進行升序排序!
db.tb_user.find({}).sort({"age":1})
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB 在讀取資料時必須掃描集合中的每個檔案並選取那些符合查詢條件的記錄。
這種掃描全集合的查詢效率是非常低的,特別在處理大量的資料時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的效能是非常致命的。
MongoDB 使用 createIndex()
方法來建立索引,語法格式如下:
db.collection.createIndex(keys, options)
語法中 Key 值為你要建立的索引欄位,1
為指定按升序建立索引,如果你想按降序來建立索引指定為 -1
即可!
例如,給tb_user
檔案中的age
建立一個索引!
db.tb_user.createIndex({"age":1})
建立索引是一個比較耗時的動作,我們還可以通過引數設定,在後臺建立索引。
db.tb_user.createIndex({"age":1}, {background: true})
通過在建立索引時加background:true
的選項,讓建立工作在後臺執行!
MongoDB 提供了getIndexes()
方法,可以進行檢視索引。
例如,查詢tb_user
集合中的索引
db.tb_user.getIndexes()
不在需要的索引,我們可以將其刪除。刪除索引時,可以刪除集合中的某一索引,可以刪除全部索引。
語法格式:
db.COLLECTION_NAME.dropIndex("INDEX-NAME")
例如,刪除集合tb_user
集合中的age
索引:
#查詢索引
db.tb_user.getIndexes()
#輸出結果
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test_db.tb_user"
},
{
"v" : 2,
"key" : {
"age" : 1
},
"name" : "age_1",
"ns" : "test_db.tb_user"
}
]
刪除對應的age_1
索引!
db.tb_user.dropIndex("age_1")
對於任何一款資料庫,如果沒有視覺化介面操作,在開發的時候,可以說極其不方便,下面推薦一款小編經常使用的一款使用者端。
其中小編採用的是第二款,整體的體驗比Robo 3T
要一點,兩者功能都比較齊全!
在使用的時候,可以根據個人喜愛進行選擇!
網上發現很多 mongodb 被黑,使大家將目光投向了mongodb 的許可權控制。
其實 mongodb 本身有一套完備的 RBAC 許可權控制體系,這次被黑基本都是沒有遵照 mongodb 的生產環境部署手冊部署的結果。
我們平時玩一玩 mongodb 習慣了不設定使用者名稱密碼,當我們的資料庫放到公網時,由於我們也沒有設定使用者名稱密碼,任何人都可以隨便存取,而且由於我們沒有開啟授權存取,使得任何登入到 mongodb 伺服器的使用者都擁有最高許可權!
一些居心不良的人發現,就可以把我們的資料拷走,刪除我們的資料庫,從而勒索贖金!
再次提醒各位同學,別學會所有的技能,大門還一直開著,還抱怨我方防禦塔怎麼一直被摧毀!
以上文CentOS7
安裝為例,修改/etc/mongod.conf
,在security
部分新增如下設定,開啟授權存取!
security:
authorization: enabled
修改完成之後,重啟 mongodb 服務
#重啟服務
systemctl restart mongod
本文主要圍繞 MongoDB 的使用,從環境設定、資料庫使用,再到使用者端工具選用,做了簡單的介紹,可能有的地方總結的不到位,歡迎各位網友批評指出!
在下篇文章中,我們會詳細的介紹SpringBoot
和MongoDB
的整合實踐!
作者:程式設計師志哥
出處:www.pzblog.cn
資源:微信搜【Java極客技術】關注我,回覆 【cccc】有我準備的一執行緒序必備計算機書籍、大廠面試資料和免費電子書。 希望可以幫助大家提升技術和能力。