一文詳解Mongodb數據庫,適合大數據存儲
什么是數據庫
在網絡交互的過程中,不僅會有數據的傳遞,也會有新數據的產生。比如我們目前的網站登錄注冊項目,在用戶注冊后,我們只是把數據添加到了服務器的內存中,但是程序一旦關閉或者重啟,內存中的數據就消失了,服務器會恢復到最初的樣子,那注冊的用戶數據也就沒有了。這對于網站來講,是不可接受的。那么如何解決這個問題呢?
服務器程序,就像是我們大腦的記憶,并不是長久的,一旦重啟,就會失憶。俗?話說,好記性不如爛筆頭。因此最好的辦法,就是把數據記錄并保存下來。
在早期的網站中,通過把數據寫入到文件中來進行保存,即便電腦關閉重啟,文件也不會消失。但慢慢的又發現了問題,當文件存儲內容過多的時候,很難找到我們想要的那條數據,而且,讀取文件也是一個非常耗時的過程。
為了能夠更好的存儲數據,數據庫應運而生,在本系列課程中,我們要使用的數據庫是MongoDB。
圖書館是一個存儲圖書的地方,糧倉是用來存儲糧食的。數據庫,顧名思義,就是專門用來存儲數據的倉庫。存儲在數據庫中的數據,能夠長期的保存,并且易于查找。
在數據庫中,數據不是雜亂無章的,它們會放在一個一個的小盒子里,在MongoDB中這些盒子就稱為集合。一個數據庫中可以有多個集合,而集合中存儲的是一條一條的數據。
MongoDB簡介
NoSQL(NoSQL = Not Only SQL ),意即"不僅僅是SQL"。
在現代的計算系統上每天網絡上都會產生龐大的數據量。
這些數據有很大一部分是由關系數據庫管理系統(RDBMS)來處理。 1970年 E.F.Codd's提出的關系模型的論文 "A relational model of data for large shared data banks",這使得數據建模和應用程序編程更加簡單。
通過應用實踐證明,關系模型是非常適合于客戶服務器編程,遠遠超出預期的利益,今天它是結構化數據存儲在網絡和商務應用的主導技術。
NoSQL 是一項全新的數據庫革命性運動,早期就有人提出,發展至2009年趨勢越發高漲。NoSQL的擁護者們提倡運用非關系型的數據存儲,相對于鋪天蓋地的關系型數據庫運用,這一概念無疑是一種全新的思維的注入。
- 易擴展: NoSQL數據庫種類繁多, 但是一個共同的特點都是去掉關系數據庫的關系型特性。 數據之間無關系, 這樣就非常容易擴展
- 大數據量,高性能: NoSQL數據庫都具有非常高的讀寫性能, 尤其在大數據量下表現優秀。 這得益于它的非關系性,數據庫的結構簡單
- 靈活的數據模型: NoSQL無需事先為要存儲的數據建立字段, 隨時可以存儲自定義的數據格式。 而在關系數據庫中, 增刪字段是一件非常麻煩的事情。
MongoDB 是由C++語言編寫的,是一個基于分布式文件存儲的開源數據庫系統。
在高負載的情況下,添加更多的節點,可以保證服務器性能。
MongoDB 旨在為WEB應用提供可擴展的高性能數據存儲解決方案。
MongoDB 將數據存儲為一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔類似于 JSON 對象。字段值可以包含其他文檔,數組及文檔數組。
- 安裝:sudo apt install -y mongodb
- 默認端口:27017
- 默認配置文件的位置:/etc/mongod.conf
- 默認日志的位置:/var/log/mongodb/mongod.log
- 查看日志:grep -v '#' /etc/mongodb.conf
創建和刪除數據庫
- 創建/切換數據庫:use DATABASE_NAME,如果數據庫不存在,則創建數據庫,否則切換到指定數據庫。沒有切換數據庫的情況下默認使用test數據庫。
- 查看所有數據庫:show dbs / show databases
- 刪除當前的數據庫:db.dropDatabase()
創建和刪除集合
- 創建集合:db.createCollection(name,options)db.createCollection('stu', { capped:true, size:200, max:2} )參數capped:默認值為false表示不設置上限,值為true表示設置上限參數size:集合所占用的字節數。 當capped值為true時,需要指定此參數,表示上限大小,當文檔達到上限時, 會將之前的數據覆蓋,單位為字節參數max:文檔最大數量
- 查看集合:show collections
- 刪除集合:db.集合名稱.drop()
- 檢查集合是否設定上限: db.集合名.isCapped()
啟動方式:測試啟動
- 啟動: sudo service mongod start
- 停止: sudo service mongod stop
- 重啟: sudo service mongod restart
啟動失敗:Failed to start mongod.service: Unit mongod.service not found.
- 解決方案
- 創建配置文件:sudo vim /etc/systemd/system/mongodb.service
- [Unit] Descriptinotallow=High-performance, schema-free document-oriented database After=network.target [Service] User=mongodb ExecStart=/usr/bin/mongod --quiet --config /etc/mongod.conf [Install] WantedBy=multi-user.target
- 啟動服務
- sudo systemctl start mongodb
- sudo systemctl status mongodb
- 檢測是否啟動成功:ps aux | grep mongod
- 永久啟動:sudo systemctl enable mongodb
生產環境正式的啟動方式
啟動: sudo mongod [--auth --dbpath=dbpath --logpath=logpath --append --fork] [-–f logfile ]
- 只以 sudo mongod 命令啟動時,默認將數據存放在了 /data/db 目錄下,需要手動創建
- --dbpath: 指定數據庫的存放路徑
- --logpath: 指定日志的存放路徑
- --append: 或--logappend 設置日志的寫入形式為追加模式
- --fork: 或-fork 開啟新的進程運行mongodb服務
- --f: 或-f 配置文件路徑(可以將上述配置信息寫入文件然后通過該文件中的參數進行加載啟動)
- --auth: 以權限認證的方式啟動
配置文件啟動
sudo mongod -f mogo_start.cfg
mongoDB支持的數據類型
mongoDB文檔存儲是使用BSON類型,BSON(BSON short for Bin-ary JSON, is a bin-ary-en-coded seri-al-iz-a-tion of JSON-like doc-u-ments)是二進制序列化的形式。類如JSON,同樣支持內嵌各種類型。
MongoDB的單個實例可以容納多個獨立的數據庫,每一個都有自己的集合和權限,不同的數據庫也放置在不同的文件中
下表為MongoDB 常用的幾種數據類型:
數據類型 | 描述 |
String | 字符串。存儲數據常用的數據類型。在 MongoDB 中,UTF-8 編碼的字符串才是合法的。 |
Integer | 整型數值。用于存儲數值。根據你所采用的服務器,可分為 32 位或 64 位。 |
Boolean | 布爾值。用于存儲布爾值(真/假)。 |
Double | 雙精度浮點值。用于存儲浮點值。 |
Array | 用于將數組或列表或多個值存儲為一個鍵。 |
Timestamp | 時間戳。記錄文檔修改或添加的具體時間。 |
Object | 用于內嵌文檔。 |
Null | 用于創建空值。 |
Date | 日期時間。用 UNIX 時間格式來存儲當前日期或時間。你可以指定自己的日期時間:創建 Date 對象,傳入年月日信息。 |
Object ID | 對象 ID。用于創建文檔的 ID。 (每個文檔都有) |
ObjectId
ObjectId 類似唯一主鍵,可以很快的去生成和排序,包含 12 bytes,含義是:
- 前 4 個字節表示創建 unix時間戳,格林尼治時間 UTC 時間,比北京時間晚了 8 個小時
- 接下來的 3 個字節是機器標識碼
- 緊接的兩個字節由進程 id 組成 PID
- 最后三個字節是隨機數
增刪改查
- 插入數據:db.集合名稱.insert(document)
- db.stu.insert({name:'xiaoming', gender:true, age:10, class:'2年4班', score:100})
- db.stu.insert([{ name:'xiaomei', gender:false, age:12, class:'2年3班', score:90 },{ name:'xiaohong', gender:false, age:12, class:'2年3班', score:96 },{ name:'Jack', gender:false, age:12, class:'2年2班', score:98 },{ name:'Allen', gender:true, age:12, class:'2年3班', score:90 }])
- 插文檔時,如果不指定_id參數,MongoDB會為文檔自動分配一個唯一的ObjectId
- mongodb的保存:db.集合名稱.save(document)
如果文檔的_id已經存在則修改,如果_id不存在則添加
- mongodb的查詢
1.db.集合名稱.find({條件文檔})
2.方法findOne():查詢,只返回第一個db.集合名稱.findOne({條件文檔})
3.方法pretty(): 將結果格式化;不能和findOne()一起使用!db.集合名稱.find({條件文檔}).pretty()
- 比較運算符
1.等于: 默認是等于判斷, 沒有運算符
2.小于:$lt (less than)
3.小于等于:$lte (less than equal)
4.大于:$gt (greater than)
5.大于等于:$gte
6.不等于:$ne
- 邏輯運算符
1.and:在json中寫多個條件即可
2.or:使用$or, 值為數組, 數組中每個元素為json
3.范圍運算符:使用$in, $nin 判斷數據是否在某個數組內
- 使用$regex編寫正則表達式:db.stu.find({name:{$regex:'^張'}})
- 自定義查詢
1.shell 是一個js的執行環境
2.使用$where寫一個函數, 返回滿足條件的數據
3.db.stu.find({ $where:function() { return this.age + 10>= 18; } })
- skip和limit分頁查詢:db.stu.find().skip((page-1)*num).limit(x)
- 投影,在查詢到的返回結果中, 只選擇必要的字段
1.db.集合名稱.find({},{字段名稱:1,...})
2.參數為字段與值, 值為1表示顯示, 值為0不顯
3.特別注意:對于_id列默認是顯示的, 如果不顯示需要明確設置為0對于其他不顯示的字段不能設置為0db.stu.find({},{_id:0,name:1,gender:1})
- 排序:db.集合名稱.find().sort({字段:1,...})
1.參數1為升序排列
2.參數-1為降序排列
3.db.stu.find().sort({score:-1,age:1})
- 統計個數
1.db.集合名稱.estimated_document_count()
2.db.集合名稱.count_documents({條件})
- 去重:db.集合名稱.distinct(字段,{條件})
- 更新:db.集合名稱.update({query}, {update}, {multi: boolean})
1.參數query:查詢條件
2.參數update:更新操作符
3.參數multi:可選,默認是false,表示只更新找到的第一條數據,值為true表示把滿足條件的數據全部更新multi參數必須和$set一起使用!
- 刪除:db.集合名稱.remove({query}, {justOne: boolean})
1.參數query:可選,刪除的?檔的條件
2.參數justOne:可選, 如果設為true或1,則只刪除一條,默認false,表示刪除全部