mongodb 數據庫詳解
第1章 數據庫管理系統
1.1 前言
01.數據的定義:文字、圖像、地理位置信息(坐標、經緯度)等
02.數據庫管理系統的定義:建立、存取和管理數據,保證數據安全和完整性的軟件
03.常見的數據庫管理系統:
關系型:MySQL、Oracle、SQL Server、Db2等
非關系型:MongoDB、Redis、HBase等
數據庫管理系統使用情況排名https://db-engines.com/en/ranking
1.2 NoSQL簡介
NoSQL=Not Only SQL,支持類似SQL的功能, 與Relational Database相輔相成
其適用於性能較高,不使用SQL意味著沒有結構化的存儲要求(SQL為結構化的查詢語句),沒有約束之後架構更加靈活
1.2.1 NoSQL數據庫四大家族
列存儲:Hbase
鍵值(Key-Value)存儲:Redis
圖像存儲:Neo4J
文檔存儲:MongoDB
1.2.2 NoSQL的優勢
高可擴展性、分布式計算、沒有復雜的關系、低成本、架構靈活、半結構化數據
第2章 MongoDB
2.1 MongoDB特性
即最像關系型數據庫的NoSQL
MongoDB與RDBMS的最大區別:
沒有固定的行列組織數據結構,即無需將不同類的數據放入多張表中建立對應關系並分別存儲其數據,而是直接放入一份文檔進行存儲
2.1.1 數據存儲格式
01. JSON
MongoDB使用JSON(JavaScript ObjectNotation)文檔存儲記錄
JSON數據庫語句可以容易被解析
Web應用大量使用
NAME-VALUE配對
02. BSON
二進制的JSON,JSON文檔的二進制編碼存儲格式
BSON有JSON沒有的Date和BinData
MongoDB中document以BSON形式存放
數據格式靈活-文檔裏嵌入文檔
1 {
2 _id: ObjectID("1"),
3 username: “Silence”,
4 regDate: “10-10-2015”,
5 scores: {
6 math: "80",
7 english: "200"
8 }
9 }
2.2 MongoDB優勢
MongoDB是開源產品,On GitHub,Licensed under the AGPL,起源&贊助by MongoDB公司,提供商業版licenses許可
01.功能
JSON文檔模型、動態的數據模式、二級索引強大(特有)、查詢功能、自動分片、水平擴展、自動復制、高可用、文本搜索、企業級安全、聚合框架MapReduce、大文件存儲GridFS、地理位置索引
支持多種存儲引擎:
02.存儲引擎比較
|
MySQL InnoDB |
MongoDB MAPI |
MongoDB WiredTiger |
事務 |
YES |
NO |
NO |
鎖粒度 |
ROW-level行級鎖 |
Collection-level |
Document-level |
Geospatial |
YES |
YES |
YES |
MVCC |
YES |
NO |
NO |
Replication |
YES |
YES |
YES |
外鍵 |
YES |
NO |
NO |
數據庫集群 |
NO |
YES |
YES |
B-TREE索引 |
YES |
YES |
YES |
全文檢索 |
YES |
YES |
YES |
數據壓縮 |
YES |
NO |
YES |
存儲限制 |
64TB |
NO |
NO |
表分區 |
YES |
YES(分片) |
YES(分片) |
03.數據庫功能和性能分布圖
2.3 數據邏輯結構
2.3.1 層次關系
文檔(document)、集合(collection)、數據庫(database)
2.3.2 層次關系圖
2.3.3 MongoDB與RDBMS數據結構邏輯對比
MongoDB |
VS |
RDBMS |
集合Collection |
-> |
表Table |
文檔Document |
-> |
行Row |
數據庫Database |
|
數據庫Database |
索引值Index |
-> |
索引值Index |
嵌入式文件Embedded Document |
-> |
合並Join |
引用Reference |
-> |
外鍵Foreign Key |
分片Shard |
-> |
分區Partition |
2.4 MongoDB適用場景
1)網站數據:MongoDB 非常適合實時的插入,更新與查詢,並具備網站實時數據存儲所需的復制及高度伸縮性
2)緩存:由於性能很高,MongoDB 也適合作為信息基礎設施的緩存層。在系統重啟之後,由 MongoDB 搭建的持久化緩存層可以避免下層的數據源過載
3)大尺寸,低價值的數據:使用傳統的關系型數據庫存儲一些數據時可能會比較昂貴,在此之前,很多時候程序員往往會選擇傳統的文件進行存儲
4)高伸縮性的場景:MongoDB 非常適合由數十或數百臺服務器組成的數據庫。MongoDB的路線圖中已經包含對 MapReduce 引擎的內置支持
5)用於對象及 JSON 數據的存儲:MongoDB 的 BSON 數據格式非常適合文檔化格式的存儲及查詢
2.4.1 MongoDB使用場景
1 我的數據量是有億萬級或者需要不斷擴容
2 需要2000-3000以上的讀寫每秒
3 新應用,需求會變,數據模型無法確定
4 我需要整合多個外部數據源
5 我的系統需要99.999%高可用
6 我的系統需要大量的地理位置查詢
7 我的系統需要提供最小的latency
8 我要管理的主要數據對象 <10
說明:以上條件滿足一個可以考慮MongoDB,滿足兩個選擇MongoDB不會後悔
第3章 MongoDB軟件安裝
3.1 前提條件
官方下載地址www.mongodb.com
安裝文檔地址
docs.mongodb.com
mongoing.com
軟件所支持的平臺(X86_64)
在3.4版更改:MongoDB不再支持32位的x86平臺
註意:切記在選擇mongodb版本時要確認支持/兼容哪些操作系統及版本信息,如使用3.2版本需安裝在CentOS6.2級以上操作系統
3.1.1 安裝前準備
01.準備Redhat或Centos6.2以上系統
02.系統開發包完整
03.關閉iptables及Selinux
04.配置IP地址和hosts解析
05.關閉hugepage大頁內存
06.創建所需用戶mongod(非root用戶)
07.創建所需目錄,並授權
3.1.1.1 具體步驟
1 [root@mongodb ~]# cat /etc/redhat-release
2 CentOS release 6.9 (Final)
3
4 [root@mongodb ~]# uname -r
5 2.6.32-696.el6.x86_64
6
7 [root@mongodb ~]# uname -m
8 x86_64
1 /etc/init.d/iptables status
2 getenforce
3 ip a
4 echo "10.0.0.51 mongodb" >>/etc/hosts
5
6 /etc/init.d/mysqld stop #若存在mysql程序需提前關閉以防止程序沖突
關閉大頁內存機制以提高性能
1 vim /etc/rc.local
2
3 #以root用戶身份在最後一行添加如下代碼,重啟生效
4 if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
5 echo never > /sys/kernel/mm/transparent_hugepage/enabled
6 fi
7 if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
8 echo never > /sys/kernel/mm/transparent_hugepage/defrag
9 fi
系統關閉參照官方文檔https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
3.2 安裝及啟動
01.創建所需用戶和組
1 groupadd -g 800 mongod 2 useradd -u 801 -g mongod mongod 3 passwd mongod
02.創建mongodb所需目錄結構
1 mkdir -p /application/mongodb/{bin,conf,log,data}
03.上傳並解壓軟件到指定位置
1 cd /application/
2
3 rz#上傳mongodb-linux-x86_64-3.2.8.tgz包
4
5 tar -zxvf mongodb-linux-x86_64-3.2.8.tgz
6 cd mongodb-linux-x86_64-3.2.8/bin/
7 cp -a * /application/mongodb/bin
04.設置目錄結構權限
1 chown -R mongod:mongod /application/mongodb
05.設置用戶環境變量
1 su - mongod
2
3 vim .bash_profile
4 export PATH=/application/mongodb/bin:$PATH
5
6 source .bash_profile
06.啟動mongodb(無需初始化)
1 mongod --dbpath=/application/mongodb/data --logpath=/application/mongodb/log/mongodb.log --port=27017 --logappend --fork
說明:在啟動mongodb要指定數據、日誌路徑及端口號(默認也可以)
06.1成功標識
about to fork child process, waiting until server is ready for connections.
forked process: 1294
child process started successfully, parent exiting
3.2.1 mongodb啟動參數詳解
mongod參數 |
參數說明 |
--dbpath |
數據存放路徑 |
--logpath |
日誌文件路徑 |
--logappend |
日誌輸出方式->以追加模式進行記錄,默認覆蓋記錄 |
--port |
啟用端口號 |
--fork |
以後臺守護進程的方式啟動 |
--auth |
是否需要驗證權限登錄(用戶名和密碼) |
--bind_ip |
限制訪問的ip |
07.編輯配置文件->以讀取配置文件的方式來啟動數據庫
1 vim /application/mongodb/conf/mongod.conf
2
3 dbpath=/application/mongodb/data
4 logptah=/application/mongodb/log/mongodb.log
5 port=27017
6 logappend=1
7 fork=1
08.指定配置文件啟動/關閉mongod
1 mongod -f /application/mongodb/conf/mongod.conf #啟動數據庫
2 mongod -f /application/mongodb/conf/mongod.conf shutdown #關閉
09.登錄mongodb
1 mongo
2
3 ###此時已登陸mongodb系統,以下為提示信息###
4 MongoDB shell version: 3.2.8
5 connecting to: test
6 >
說明:
01.初次登錄時默認提示版本號信息及連接數據庫test,但是在MongoDB中test數據庫默認並不存在
02.對於3.2以上版本默認只有一個admin數據庫,且無需提前創建,不存在的庫也能夠正常use
3.2.2 啟動時報錯:"WARNING: soft rlimits too low. rlimits set to 1024 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files"的類似錯誤
報錯原因:rlimits設置過小,其設置幾乎不能滿足MongoDB運行所需的最小條件,會導致它運行緩慢甚至出現不可知的錯誤
解決思路:
01.查看當前的MongoDB進程信息
1 ps -ef | grep mongod
2
3 #結果如下
4 mongod 1982 1 0 11:47 ? 00:00:16 mongod --dbpath=/application/mongodb/data --logpath=/application/mongodb/log/mongodb.log --port=27017 --logappend --fork
5 root 2056 1566 0 12:21 pts/1 00:00:00 grep --color=auto mongod
02.查看mongod進程的系統限制
1 cat /proc/1982/limits
2
3 #結果如下
4 Limit Soft Limit(軟限制->最小值) Hard Limit(硬限制->最大值) Units
5 Max processes 1024 64000 processes
6 Max open files 65535 65535 files
解決方法:
①方法一
1 vim /etc/security/limits.d/90-nproc.conf
2 * soft nproc 32000 #此為修改後結果,reboot重啟生效
②方法二
1 vim /etc/security/limits.conf
2
3 # End of file
4 mongod soft nofile 64000
5 mongod hard nofile 64000
6 mongod soft nproc 32000
7 mongod hard nproc 32000
查看系統限制
1 ulimit -a
#也可利用ulimit [-ftvnmu]命令在shell命令行中直接進行設置
#但若要系統啟動時在所有窗口生效,需將上面的ulimit添加到/etc/profile
3.2.3 YAML模式編寫配置文件
1 systemLog:
2 destination: file
3 path: "/application/mongodb/log/mongod.log"
4 logAppend: true
5 storage:
6 journal:
7 enabled: true
8 dbPath: "/application/mongodb/data"
9 processManagement:
10 fork: true
11 net:
12 port: 27017
此時關閉mongodb重新啟動即可
3.2.4 MongoDB的關閉方式
3.2.4.1 kill進程模式(不建議使用)
1 $ kill -2 PID #原理:-2表示向mongod進程發送SIGINT信號
2 或
3 $ kill -4 PID #原理:-4表示向mognod進程發送SIGTERM信號
3.2.4.2 自帶模式
1 use admin
2
3 admin> db.adminCommand({shutdown:1})
4 或
5 $ mongod -f mongodb.conf --shutdown
6 killing process with pid: 1621
註意:
01.mongod進程收到SIGINT或SIGTERM信號,會做一些處理
02.切忌使用kill -9
3.2.5 編輯腳本實現SYS-V形式啟動mongod
mongod.conf3.3 基本操作及使用
獲取幫助
1 > help
help幫助信息查看當前db版本
1 > db.version()
2 3.2.8
查看當前使用db
1 > db
2 test
3 或
4 > db.getName()
5 test
查詢所有數據庫
1 > show dbs
2 local 0.000GB
切庫
1 > use test
2 switched to db test
顯示當前數據庫狀態
1 > db.stats()
2 {
3 "db" : "local",
4 "collections" : 1,
5 "objects" : 7,
6 "avgObjSize" : 1466,
7 "dataSize" : 10262,
8 "storageSize" : 36864,
9 "numExtents" : 0,
10 "indexes" : 1,
11 "indexSize" : 36864,
12 "ok" : 1
13 }
查看當前數據庫的連接機器地址
1 > db.getMongo()
2 connection to 127.0.0.1
創建數據庫
當使用use命令時系統會自動創建一個數據庫,如果use之後沒有創建任何集合,系統就會刪除這個數據庫
1 > use banana
2 switched to db banana
刪除數據庫
如果沒有選擇任何數據庫,會刪除默認的test數據庫
1 > db.dropDatabase()
2 { "ok" : 1 }
3 > show dbs;
4 local 0.000GB
創建集合
方法1:
1 > use banana;
2 switched to db banana #相當於use banana ,不同的是(從mysql關系型數據庫角度解釋),在mongodb中banana允許未創建情況下use banana,在創建數據表後,即創建了banana,否則banana不會創建
3 > db.createCollection(‘a‘); #創建集合a,a相當於mysql中的數據表
4 { "ok" : 1 } # 提示創建成功
5 > db.createCollection(‘b‘);
6 { "ok" : 1 }
7 > show collections;
8 a
9 b
方法2:
1 > db.c.insert({username:"mongodb"}) #向c集合插入數據
2 WriteResult({ "nInserted" : 1 }) ->成功寫入文檔
3
4 > show collections
5 a
6 b
7 c
8 > db.c.find() #顯示數據集合中所有數據,當前僅一條
9 { "_id" : ObjectId("5743c9a9bf72d9f7b524713d"), "username" : "mongodb" }
10 > db.log.find().pretty(); # 格式化打印結果
11 {
12 "_id" : ObjectId("5743c9a9bf72d9f7b524713d"),
13 "uid" : 0,
14 "name" : "mongodb",
15 "age" : 6,
16 "date" : ISODate("2018-01-03T08:37:00.214Z")
17 }
18
19 > db.c.drop() #刪除c集合
20 true
21 > db.c.find() #c集合置空
批量插入數據
1 > for(i=0;i<10000;i++){ db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()}); } #批量插入10000個數據
2
3 #查詢集合中的記錄數
4 > db.log.find()
說明:默認每頁顯示20條記錄,當顯示不下的的情況下,可以用it叠代命令查詢下一頁數據
1 #設置每頁顯示數據的大小:每頁顯示50條記錄
2 > DBQuery.shellBatchSize=50;
3 #查看第1條記錄
4 > db.log.findOne()
5 #查詢總的記錄數
6 > db.log.count()
7 #刪除集合中所有記錄
8 > db.log.remove({})
9 #集合中數據的原始大小
10 > db.log.dataSize()
11 #集合中索引數據的原始大小
12 > db.log.totalIndexSize()
13 #集合中索引+數據壓縮存儲之後的大小
14 > db.log.totalSize()
15 #集合中數據壓縮存儲的大小
16 > db.log.storageSize()
mongodb 數據庫詳解