爲什麼使用數據庫
原本存儲數據的方式比如使用 Excel,不適合存儲大量數據,也不適合需求變得複雜的環境。Excel 的儲存量有限,訪問速度及處理速度在數據量大時也是短板,且擴展性(兼容性)是遠遠不如數據庫的。
數據庫相關概念
數據庫(DB)Database:是按照數據結構來組織、存儲和管理數據的倉庫。
數據庫管理系統(DBMS):是專門用於管理數據庫的計算機系統軟件。
數據庫管理系統能夠爲數據庫提供數據的定義、建立、維護、查詢和統計等操作功能,並完成對數據完整性、安全性進行控制的功能。
DBA:數據庫是一門學科,專門做數據庫運維的人叫 Database Administrator。
數據庫分類
分爲兩大類:關係型數據庫和非關係數據庫。
- 關係型數據庫是由多張能互相聯接的二維行列表格組成的數據庫。典型的代表:MySQL、PostgreSQL、SQlServer、Oracle、DB2 等。
- NoSQL(Not Only SQL),非關係型數據庫,典型的代表:MongoDB,Redis,HBase,CouchDB 等。
NoSQL
NoSQL 分類:
- 鍵值(Key-Value)存儲數據庫:這一類數據庫主要會使用到一個哈希表,這個表中有一個特定的鍵和一個指針指向特定的數據;
- 列存儲數據庫:這部分數據庫通常是用來應對分佈式存儲的海量數據。鍵仍然存在,但是它們的特點是指向了多個列;
- 文檔型數據庫:同第一種鍵值存儲相類似。該類型的數據模型是版本化的文檔,半結構化的文檔以特定的格式存儲;
- 圖形(Graph)數據庫:使用圖模型存儲。
常見 NoSQL 數據庫:
- MongoDB:文檔型數據庫;功能豐富;查詢語言強大;併發效率不高,查詢效率不算高;
- Redis:field-value 存儲系統(主要面對內存數據庫,也可持久化);安全性;主從複製;運行異常快,支持事務,豐富類型的 field 類型。
關係型數據庫 VS 非關係型數據庫
非關係型數據庫的優勢:
- 無需 SQL 的解析,所以性能非常高。有可以做的純內存操作,比如 Redis,單節點每秒可以處理超過 10 萬次讀寫操作。
- NoSQL 數據庫是動態結構,可以很容易適應數據類型和結構的變化。
- 容易集羣。
關係型數據庫的優勢:
- 複雜查詢,可以用 SQL 語句方便的在多個表之間做非常複雜的數據查詢。
- 事務支持,使得對於安全性能很高的數據訪問要求得以實現。
NoSQL 用於超大規模數據的存儲。(例如谷歌或 Facebook 每天爲他們的用戶收集萬億比特的數據)。這些類型的數據存儲不需要固定的模式,無需多餘操作就可以橫向擴展。
MongoDB 簡介
1)前景
隨着大數據的不斷髮展,非關係型數據庫已經變得越來越重要,相關的產品也都得到了飛速發展。
而其中 MongoDB 更是佼佼者,作爲高性能開源文檔數據庫,MongoDB 以敏捷、可擴展和對企業應用友好而著稱,因其操作簡單、完全免費、源碼公開等特點,受到了 IT 從業人員的青睞,並被廣泛部署於實際的生產環境中。
使用 MongoDB 的公司包括:BAT、360、Foursquare、Craiglist、迪士尼、SAP、Intuit、EA 等。
2)定義
MongoDB 是一個基於分佈式文件存儲的數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。
MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。
它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。
MongoDB 最大的特點是它支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。
3)數據模型
4)優點
MongoDB 的特點是高性能、易部署、易使用,存儲數據非常方便。
主要功能特性有:
- 面向集合存儲,易存儲對象類型的數據。
- 模式自由。
- 支持動態查詢。
- 支持完全索引,包含內部對象。
- 支持查詢。
- 支持複製和故障恢復。
- 使用高效的二進制數據存儲,包括大型對象(如視頻等)。
- 自動處理碎片,以支持雲計算層次的擴展性
- 支持 RUBY,PYTHON,JAVA,C++,PHP, JavaScript 等多種語言。
- 文件存儲格式爲 BSON(一種 JSON 的擴展)
5)BSON
BSON 是一種類似 JSON 的二進制形式的存儲格式,簡稱 Binary JSON,它和 JSON 一樣,支持內嵌的文檔對象和數組對象,但是 BSON 有 JSON 沒有的一些數據類型,如 Date 和 BinData 類型。
後面存在 MongoDB 數據庫裏面的全部都是 BSON 格式的數據。
MongoDB 安裝
1)安裝流程
安裝成功之後,會自動註冊一個 MongoDB 服務(Windows 中可以通過運行 services.msc),此服務開機自動啓動(也可以配置手動啓動)。
注意:要使用 MongoDB,此服務需運行中。
2)配置環境變量
配置環境變量可在任意位置使用 MongoDB 的命令。
找到系統屬性,高級系統設置,環境變量,配置舉例:
path=...;E:\dev\MongoDB\Server\4.0\bin
3)測試
打開命令行:輸入 mongo,若出來如下內容,證明安裝成功。
MongoDB 使用
對 MongoDB 數據庫操作需要其提供的內置命令來操作的。
1)基本命令
- show dbs:查看有數據的庫;
- use 庫名:若沒有則創建庫並切換,若有隻切換庫;
- db:顯示當前操作的庫;
- db.runCommand({"dropDatabase": 1}):刪除當前數據庫,注意此處的 1 沒加雙引號。
2)集合操作
- show collections :顯示庫中的集合;
- db.createCollection("集合名字") : 創建集合;
- db.集合名.drop() 或 db.runCommand({"drop":"集合名"}) :刪除集合。
3)文檔操作
增加文檔
給某集合裏面增加文檔,注意:
- 若集合不存在,會自動創建集合;
- 保存成功之後,系統會自動給文檔增加一個 _id 主鍵字段,主鍵是每個文檔的唯一標識,其值不能重複,就像身份證是每個人編號是唯一的。
語法格式如下:
- db.集合名.insert(BSON 格式數據),若新增的文檔主鍵已經存在,insert 會不做操作並提示錯誤;
- db.集合名.save(BSON 格式數據),若新增的文檔主鍵已經存在,save 則更改原來的內容爲新內容。
db.students.insert({"name":"xx","age":18})
db.students.insert({"_id":ObjectId("5c457f78034a8e64b22cd683"),"name":"xx","age":19}) // 報錯 duplicate field error collection
db.students.save({"_id":ObjectId("5c457f78034a8e64b22cd683"),"name":"xx","age":19}) // 修改
查詢文檔
查詢集合中的文檔,語法格式如下:
- db.集合名.find() :查詢集合中所有文檔;
- db.集合名.find().pretty() :格式化查詢到的文檔;
- db.集合名.findOne() :查詢集合中的第一個文檔,即插入最早那個。
db.students.find()
db.students.find().pretty()
db.students.findOne()
修改文檔
修改集合中的文檔,語法格式如下:
- db.集合名.update(BSON 格式數據):注意:第一個參數查詢的條件,第二個參數是修改的內容,但主鍵是不能修改。
db.students.update({"name":"xx"}, {"age":88}) // 注意原來的數據只剩下 {"age":88}
db.students.update({"name":"xx"}, {$set:{"age":88}}) // 這裏就只改原來文檔的 age 的值。
db.students.update({"name":"xx"}, {$set:{"age":88}}, {multi:true}) // 默認只改先找的一條,若想改多條得設置 multi 參數爲 true
刪除文檔
刪除集合中的文旦,語法格式如下:
- db.集合名.remove() :刪除集合中的文檔,可以指定條件。
db.集合名.remove({}) // 刪除集合中所有的文檔
db.集合名.remove({"name":"yy"}) // 刪除指定條件 name="yy" 的文檔
高級查詢
1)查詢 field = value 的文檔語法:db.集合名.find({ "field" : value })
// 查詢女歌星,即查詢 sex = "女"的歌星
db.singers.find({"sex":"女"})
2)查詢 field > value 的文檔語法:db.集合名.find({ "field" : { $gt: value } })
// 查詢年齡大於 53 的歌星
db.singers.find({"age": { $gt: 53 }})
3)查詢 field < value 的文檔語法:db.集合名.find({ "field" : { $lt: value } })
// 查詢年齡小於 35 歲的歌星
db.singers.find({"age": { $lt: 35 }})
4)查詢 field >= value 的文檔語法:db.集合名.find({ "field" : { $gte: value } })
// 查詢成績大於等於 95 的歌星
db.singers.find({"score": { $gte: 95 }})
5)查詢 field <= value 的文檔語法:db.集合名.find({ "field" : { $lte: value } })
// 查詢年齡在小於等於 32 歲的歌星。
db.singers.find({"age": { $lte: 32 }})
6)查詢 min < field < max 的文檔語法:db.集合名.find({ "field" : { $gt: min , $lt: max } })
// 查詢年齡在 (30, 40) 歲之間的歌星
db.singers.find({"age": { $gt: 30 , $lt: 40 }})
7)查詢 field <> value 的文檔語法:db.集合名.find({ "field" : { $ne: value } })
// 查詢外國歌手
db.singers.find({"country": { $ne: "中國" }})
8)查詢 field % divisor == remainder 的文檔語法:db.集合名.find({ "field" : { $mod : [ divisor, remainder ] } })
// 查詢成績爲 5,15,25...95 的歌星。
db.singers.find({"score" : { $mod : [10, 5] }})
9)查詢 field = value1 OR field = value2 ... OR field = valueN OR 的文檔語法:db.集合名.{ field: { $in: [value1, value2, ... valueN ] } }
// 查詢序號(num)爲 3 或者 6 或者 9 的歌星
db.singers.find({ "num" : { $in: ["3", "6", "9"] } })
10)查詢 field <> value1 AND field <> value2 ... AND field <> valueN 的文檔語法:db.集合名.{ field: { $nin: [value1, value2, ... valueN ] } }
// 查詢國籍不爲美國和韓國的歌手
db.singers.find({"country" : { $nin: ["美國", "韓國"] }})
11)查詢文檔字段數量的語法:db.集合名.find({ "field" : { $size: num } }),注意 field 的值是數組。
// 查詢有 3 個代表作品的歌手
db.singers.find({"works" : { $size: 3 }})
12)查詢存在或不存在某個字段的的文檔語法:db.集合名.find({ "field" : { $exists : true|false } })
// 查詢包含 name 字段的歌手
db.singers.find({"name" : { $exists : true }})
13)查詢多個條件是或的關係的文檔語法:db.集合名.find({ $or : [expression1, expression2, ..., expressionN] })
// 查詢名詞是劉德華的歌手或者是女歌手
db.singers.find({$or : [{"name":"劉德華"}, {"sex":"女"}]})
14)查詢多個條件是且的關係的文檔語法:db.集合名.find({ $and : [expression1, expression2, ..., expressionN] })
// 查詢名字是劉德華且是女的歌手
db.singers.find({$and : [{"name":"劉德華"}, {"sex":"女"}]})
15)若字段的值是對象:db.集合名.find({ "字段名.對象屬性名":對象屬性值 })
db.students.insert({"name":"zs", "score":{"yw":80, "sx":91}})
db.students.insert({"name":"ls", "score":{"yw":77, "sx":95}})
// 查詢語文成績爲 80 的同學
db.students.find({"score.yw": 80})
16)排序查詢文檔,語法格式:db.集合名.find().sort({ "field" : -1 | 1}),注意 1 代表升序,-1 代表降序
// 對所有歌星安年齡排序
db.singers.find().sort({"age": 1})
17)限制查詢的個數,語法格式:db.集合名.find().limit(n)
// 實現輸出 5 條
db.singers.find().limit(5)
18)跳過多少條再查詢,語法格式:db.集合名.find().skip(n)
// 跳過 5 條查詢
db.list.find().skip(5)
19)分頁查詢:語法格式:db.集合名.find().skip(n).limit(n)
// 假如 101 條數據,每頁顯示 10 條,一共分 11 頁,那麼要查詢第 2 頁的文檔
// var pageSize = 10;
// var start = (2 - 1) * pageSize;
db.list.find().skip(start).limit(pagesize)
索引
索引支持MongoDB中查詢的高效執行。如果沒有索引,MongoDB必須執行集合掃描,即掃描集合中的每個文檔,以選擇與查詢語句匹配的文檔。如果查詢存在適當的索引,MongoDB可以使用索引來限制它必須檢查的文檔數。即可以使查詢更高效。
具體可以查看MongoDB中文社區:http://www.mongoing.com/archives/26867。
另外,可以查看索引的應用例子:MongoDB地理索引。
權限
讓數據安全, 避免數據泄露和丟失。
1)添加超級管理員用戶
use admin
db.createUser({"user":"用戶名", pwd:"密碼","roles"["root"]})
2)修改配置文件開啓認證
修改 MongoDB 根目錄下的 mongod.cfg 文件
security:
authorization: enabled
3)重啓數據庫之後使用戶名和密碼連接數據庫
mongo -u 用戶名 -p 密碼