一、MongoDB 基礎概念
1. 什么是 MongoDB
- MongoDB 是一個文檔型數據庫,數據以類似 JSON 的文檔形式存儲,使用 BSON 格式。
- 設計理念是應對大數據量1、高性能和靈活性需求。
- 數據組織方式:數據庫→2集合→文檔,其中集合類似于關系型數據庫的表,文檔類似于行。
2. 主要特點
3456-?文檔導向存儲:以 JSON-like 格式存儲,數據結構靈活。
- 索引優化查詢:7可對任意屬性創建索引,提升查詢效率。
- *數據鏡像與擴展性8*:通過副本集實現數據冗余和高可用。
- 水平擴展與分片9:利用分片技術將數據分布到多個節點。
- 強大的查詢語言10:支持復雜查詢表達式,包括內嵌對象和數組查詢。
- 靈活的數據更新11:使用 update () 命令可替換整個文檔或更新指定字段。
- MapReduce1213批量處理:用于大規模數據處理和聚合操作,Map 和 Reduce 函數用 JavaScript 編寫。
- GridFS 大文件1415存儲:存儲和檢索大于 BSON 文檔大小限制的文件。
- 多語言支持:支16持 RUBY、PYTHON、JAVA 等多種編程語言。
3. 核心概念對3比
SQL 術語 / 概念 | MongoDB 術語 / 概念 | 解釋 / 說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表 / 集合 |
row | document | 數據記錄行 / 文檔 |
column | field | 數據字段 / 域 |
index | index | 索引 |
primary key | primary key | 主鍵,MongoDB 自動將_id 字段設置為主鍵 |
table joins | - | 表連接,MongoDB 不支持 |
二、MongoDB 安裝與啟動
1. 安裝前準備
- 安裝 Linux 平臺依賴包:
dnf install libcurl openssl -y
。 - 下載 MongoDB 安裝17包并解壓:
tar -zxvf mongodb-linux-x86_64-rhel8-8.0.8.tgz
。 - 將解壓包拷貝到指定目錄18:
mv mongodb-linux-x86_64-rhel88-8.0.8 /usr/local/mongodb
。
2. 配置環境變19量
- 將 MongoDB 可執行文件添加到 PATH 路徑:
echo 'export PATH=/usr/local/mongodb/bin:$PATH' > /etc/profile
source /etc/profile
3. 創建數據庫目20錄
- 數據存儲目錄:
/var/lib/mongodb
。 - 日志文件目錄:
/va{insert\_element\_16\_}r/log/mongodb
。 - 創建目錄并設置權限:
22```bash
mkdir -p /var/lib/mongo
mkdir -p /var/log/mongodb
chown whoami /var/lib/mongo
chown whoami /var/log/mongodb
### 4. 編譯安裝Op{insert\_element\_18\_}enSSL11
- 安裝編譯工具:`dnf install -y gcc make perl`。
- 配置、編譯和安裝Ope{insert\_element\_19\_}nSSL:
```bash
tar xzf openssl-1.1.w.tar.gz
cd openssl-1.1.1w
./config -prefix=/opt/openssl11 --openssldir=/opt/openssl/ssl
make -j$(nproc)
make install
5. 設置 Open24SSL11 環境變量
echo 'export LD_LIBRARY_PATH=/opt/openssl11/lib:$LD_LIBRARY_PATH' | sudo tee /etc/profile.d/openssl11.sh
source /etc/profile.d/openssl11.sh
6. 啟動 Mong25oDB 服務
mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork
啟動成功后會顯示子進程啟動信26息。
三、MongoDB27?Shell 使用
1. 安裝 MongoDB Shell
- 解壓安裝包并復制 mongosh 二進制文件到 PATH 目錄:
tar xzf mongosh-2.5.0-linux-x64-openssl3.tgz
cd mongosh-2.5.0-linux-x64-openssl3/bin
cp mongosh /usr/local/bin/
cp mongosh_crypt_v1.so /usr/local/lib/
2. 連接 Mong28oDB 服務器
- 基本連接命令:
mongosh --host <hostname> --port <port>
。 - 默認連接本地服務器:
{insert\_element\_25\_}mongosh
,成功連接后會顯示 MongoDB 和 mongosh 版本信息。
四、數據庫管理、
?1. 查看數據庫
- 查看所有數據庫:
show dbs
。 - 查看當前使用的數據庫:31
db
。
2. 創建數據庫32
- 使用
use DATABASE_NAME
命令,若數據庫不存在則自動創建。 - 示例:
use runoob
switched to db runoob
3. 刪除數據庫
34- 使用db.dropDatabase()
方法。
- 示例:
use myDatabase
db.dropDatabase()
4. 默認與系統數36據庫
- 默認數據庫:test,未指定數據庫時數據默認存儲在此。
- 系統內置數據庫37:
- admin:存儲用戶身份信息和全局權限。
- config:分片38集群中存儲分片元數據。
- local:存儲當39前節點的副本集狀態和操作日志。
五、集合管理
?1. 查看集合
- 使用
show collections
或show tables
命令。
2. 創建集合
41- 使用db.createCollection(name, options)
方法。
- 示例:創建固定大小集合
db.createCollection("myComplexCollection", {capped: true,size: 10485760,max: 5000,validator: {$jsonSchema: {required: ["name", "email"],bsonType: "object",properties: {name: { bsonType: "string" },email: { bsonType: "string", pattern: ".+@.+" }}}},validationLevel: "strict",storageEngine: { wiredTiger: { configString: "block_compressor=zstd" } }
})
3. 重命名集合
43- 使用db.adminCommand({ renameCollection: "sourceDb.sourceCollection", to: "targetDb.targetCollection" })
。
4. 刪除集合
44- 使用db.collection.drop()
方法。
六、文檔操作
?1. 插入文檔
- insertOne():插入單個文檔。
javascri{insert_element_42_}pt
db.myCollection.insertOne({ name: "Alice", age: 25, city: "New York" })
- insertMany():插入多個文檔。
javascri{insert_element_43_}pt
db.myCollection.insertMany([{ name: "Bob", age: 30, city: "Los Angeles" },{ name: "Charlie", age: 35, city: "Chicago" } ])
2. 查詢文檔
- find():查找多個文檔。
- 查找所有:
db.{insert\_element\_44\_}myCollection.find()
。 - 按條件查找:
db.myCollection.find({ age: { $gt: 25 } })
。
- 查找所有:
- findOne()49:查找單個文檔。
db.myCollection.findOne({ name: "Alice" })
3. 刪除文檔
- deleteOne():刪除單個匹配文檔。
db.myCollection.deleteOne({ name: "Alice" })
- deleteMany():刪除所有匹配文檔。
db.myCollection.deleteMany({ name: "Bob" })
4. 更新文檔
- updateOne():更新單個匹配文檔。
db.myCollection.updateOne({ name: "Alice" }, { $set: { age: 26 } })
- updateMany():更新所有匹配文檔。
db.myCollection.updateMany({ age: { $lt: 30 } }, { $set: { status: "active" } })
- replaceOne():替換單個匹配文檔。
db.myCollection.replaceOne({ name: "Bob" }, { name: "Bob", age: 31 })
七、MongoDB 備份與恢復
1. 安裝備份與恢復工具
rpm -ivh mongodb-database-tools-rhel70-x86_64-100.12.0.rpm
2. 數據備份(m56ongodump)
- 基本命令:
mongodump -h dbhost -d dbname -o dbdirectory
。 - 示例:備份所有數據到當57前目錄下的 dump 目錄
mongodump
3. 數據恢復(m58ongorestore)
- 基本命令:
mongorestore -h <hostname>:<port> -d dbname <path>
。 - 示例:從默認 dump 目59錄恢復數據
mongorestore
八、用戶管理
1. 創建用戶
db.createUser({user: "testuser",pwd: "password123",roles: [{ role: "readWrite", db: "database_name" },{ role: "dbAdmin", db: "database_name" }]
})
2. 驗證用戶
### 3. 啟用身份驗證{insert\_element\_58\_}
- 編輯配置文件`mongod.conf`,添加:
```yaml
security:authorization: "enabled"
- 或在啟動命令中添加
--{insert\_element\_59\_}auth
參數。
4. 使用用戶登錄
mongosh --host hostname --port port -u "testuser" -p "password123" --authenticationDatabase "database_name"
5. 刪除用戶
{insert\_element\_62\_}
九、索引管理
1. 索引基礎
- 索引作用:優化查詢性能,基于集合字段創建數據結構。
- 創建索引:
d{insert\_element\_0\_}b.collection.createIndex( { field: 1 }, { options } )
,1 為升序,-1 為降序。 - 唯一索引:
db.users.createIndex( { email: 1 }, { unique: true } )
,確保字段值唯一。
2. 復合索引
- 基于多個字段創建索引,語法:
db.collection.createIndex( { field1: 1, field2: -1 } )
。 - 注意:查詢條件需包含索引前綴字段才能有效利用復合索引。
3. 索引查看與刪除
- 查看所有索引:
db.collection.getIndexes()
。 - 刪除指定索引:
db.collection.dropIndex( "indexName" )
。 - 刪除所有索引:
db.collection.dropIndexes()
。
4. 地理空間索引
- 用于地理位置相關查詢,創建 2dsphere 索引:
db.places.createIndex( { location: "2dsphere" } )
。 - 查詢示例:查找半徑 5 公里內的地點:
db.places.find( {location: {$near: {$geometry: { type: "Point", coordinates: [116.4074, 39.9042] },$maxDistance: 5000}}
} )
十、聚合框架(Aggregation Framework)
1. 聚合管道概念
- 通過多個階段(stage)處理數據,每個階段對文檔進行轉換。
- 常見階段:、group、、sort、$limit 等。
2. 基本聚合操作
- $match:過濾文檔,類似 find 的查詢條件:
db.sales.aggregate( [ { $match: { category: "electronics", price: { $gt: 100 } } } ] )
- $group:分組聚合,_id 指定分組字段,可使用聚合表達式:
db.sales.aggregate( [{ $group: { _id: "$category", totalSales: { $sum: "$price" } } } ] )
- $project:投影字段,控制輸出內容:
db.sales.aggregate( [{ $project: { product: 1, price: 1, discount: { $multiply: [ "$price", 0.8 ] } } } ] )
3. 高級聚合操作
- $lookup:左關聯查詢,類似 SQL 的 LEFT JOIN:
db.orders.aggregate( [{$lookup: {from: "customers",localField: "customerId",foreignField: "_id",as: "customerInfo"}} ] )
- $unwind:展開數組字段,將每個數組元素轉為獨立文檔:
db.products.aggregate( [ { $unwind: "$tags" } ] )
4. 聚合表達式
- 數學表達式:、avg、、max。
- 條件表達式:、ifNull、$switch。
- 字符串表達式:、substr、$toUpper。
十一、分片集群(Sharding)
1. 分片架構組件
- 分片節點(Shard):存儲實際數據,可由副本集組成。
- 配置服務器(Config Server):存儲分片元數據(如數據分布信息)。
- 路由節點(MongoS):客戶端連接入口,負責轉發請求到對應分片。
2. 分片部署步驟
- 啟動配置服務器:
mongod --configsvr --dbpath /data/config --port 27019
。 - 啟動分片節點(副本集):
mongod --shardsvr --dbpath /data/shard1 --port 27017 --replSet rs1 mongod --shardsvr --dbpath /data/shard2 --port 27018 --replSet rs1
- 初始化副本集:
rs.initiate()
。 - 啟動路由節點:
mongos --configdb configServerHost:27019
。 - 將分片添加到集群:
sh.addShard( "rs1/host1:27017,host2:27018" )
。 - 啟用分片:
sh.enableSharding( "databaseName" )
。 - 設置分片鍵:
sh.shardCollection( "databaseName.collectionName", { shardKey: 1 } )
。
3. 分片鍵選擇
- 范圍分片鍵:如時間字段,數據按范圍分布,適合時序數據。
- 哈希分片鍵:如用戶 ID 的哈希值,數據均勻分布,適合高并發寫入。
- 復合分片鍵:如 {region: 1, date: 1},結合范圍和哈希優勢。
十二、副本集(Replica Set)
1. 副本集架構
- 主節點(Primary):處理所有寫入操作,同步數據到從節點。
- 從節點(Secondary):復制主節點數據,處理讀請求。
- 仲裁節點(Arbiter):不存儲數據,僅參與選舉決策。
2. 副本集初始化
// 連接到主節點
mongosh --port 27017
// 定義副本集配置
config = {_id: "rs0",members: [{ _id: 0, host: "server1:27017" },{ _id: 1, host: "server2:27017" },{ _id: 2, host: "server3:27017", arbiterOnly: true }]
}
// 初始化副本集
rs.initiate( config )
3. 故障轉移與讀偏好
- 自動故障轉移:主節點故障時,從節點通過選舉產生新主節點。
- 讀偏好(Read Preference):
- primary:只從主節點讀取(默認)。
- primaryPreferred:優先從主節點讀取,不可用時從從節點。
- secondary:只從從節點讀取。
- secondaryPreferred:優先從從節點讀取,不可用時從主節點。
- nearest:從最近的節點讀取。
十三、事務管理
1. 事務特性
- ACID 特性:MongoDB 4.0 + 支持分布式事務,確保原子性、一致性、隔離性、持久性。
- 多文檔事務:跨文檔、跨集合、跨數據庫的操作作為原子單元。
2. 事務使用示例
// 開始事務
const session = db.getMongo().startSession();
try {session.startTransaction();// 操作1:更新賬戶A余額db.accounts.updateOne({ _id: "A" },{ $inc: { balance: -100 } },{ session });// 操作2:更新賬戶B余額db.accounts.updateOne({ _id: "B" },{ $inc: { balance: 100 } },{ session });// 提交事務await session.commitTransaction();console.log("轉賬成功");
} catch (error) {// 回滾事務await session.abortTransaction();console.error("轉賬失敗:", error);
} finally {session.endSession();
}
3. 事務注意事項
- 事務超時時間默認 60 秒,可通過
maxTransactionTimeMS
參數調整。 - 分片集群中事務需使用 MongoDB 4.2+,且配置服務器為副本集。
- 避免長事務,減少鎖競爭。
十四、存儲引擎
1. WiredTiger(默認)
- 特點:支持文檔級鎖、壓縮、加密,性能均衡,適合大多數場景。
- 壓縮算法:
- zlib:壓縮率高,CPU 消耗大。
- snappy:壓縮率低,速度快。
- zstd:平衡壓縮率和速度(默認)。
- 配置示例:在 mongod.conf 中設置
storage.wiredTiger.engineConfig.compressor = zstd
。
2. MMAPv1(舊版)
- 特點:使用文件映射內存,支持表級鎖,不推薦新部署。
- 適用場景:遺留系統兼容,或需要特定功能(如稀疏集合)。
3. In-Memory
- 特點:數據全部存儲在內存,適合對響應時間要求極高的場景。
- 注意:重啟后數據丟失,需搭配持久化存儲。
十五、監控與性能調優
1. 內置監控命令
- 查看服務器狀態:
db.serverStatus()
,獲取內存、CPU、IO 等指標。 - 查看當前操作:
db.currentOp()
,查看正在執行的命令。 - 慢查詢日志:啟用慢查詢日志(默認超過 100ms):
bash
mongod --slowms 50 --logpath /var/log/mongodb/mongod.log
2. 性能調優策略
- 索引優化:為頻繁查詢的字段創建索引,避免全表掃描。
- 批量操作:使用 insertMany、bulkWrite 替代單條插入,減少網絡開銷。
- 連接池優化:調整驅動程序的連接池大小,默認值通常足夠。
- 內存配置:WiredTiger 存儲引擎建議將 50% 物理內存分配給緩存。
- 磁盤 IO:使用 SSD 存儲數據,避免頻繁寫入導致磁盤瓶頸。
3. 監控工具
- MongoDB Compass:圖形化工具,查看性能指標和查詢分析。
- MongoDB Atlas:云服務自帶監控儀表盤。
- Prometheus + Grafana:通過 MongoDB Exporter 采集指標并可視化。
十六、應用場景
1. 內容管理系統
- 靈活的數據結構適合存儲博客、文章等內容,支持動態字段擴展。
- 案例:WordPress 插件、新聞門戶網站。
2. 實時數據分析
- 聚合框架和 MapReduce 支持快速處理海量數據,如用戶行為分析。
- 案例:電商平臺商品瀏覽統計、廣告點擊分析。
3. 物聯網(IoT)數據存儲
- 分片集群支持海量設備數據存儲,時間序列數據查詢優化。
- 案例:智能家居設備日志、工業傳感器數據采集。
4. 社交網絡應用
- 文檔模型適合存儲用戶關系、動態等復雜結構,支持高并發讀寫。
- 案例:社交平臺消息系統、用戶資料管理。
5. 移動應用后端
- 多語言驅動和云服務(MongoDB Atlas)簡化移動應用開發。
- 案例:移動游戲進度存儲、社交 APP 用戶數據。
十七、最佳實踐
1. 數據模型設計
- 嵌入 vs 引用:
- 多對一關系:嵌入子文檔(如用戶包含地址)。
- 多對多關系:使用引用 + 索引(如用戶與角色關聯)。
- 避免過度規范化:適當冗余字段減少查詢關聯。
2. 安全配置
- 啟用身份驗證,分配最小權限角色。
- 禁止公網直接訪問 MongoDB 服務,使用 VPN 或防火墻限制。
- 啟用 TLS/SSL 加密通信:
mongod --ssl --sslCertificateKeyFile cert.pem
。
3. 備份與恢復策略
- 定期全量備份(如每天)+ 增量備份(如每小時)。
- 測試備份恢復流程,確保數據可恢復。
- 異地災備,防止物理故障導致數據丟失。
4. 版本升級
- 先在測試環境驗證新版本兼容性,尤其注意廢棄功能。
- MongoDB 4.4 + 支持滾動升級,減少服務中斷時間。
- 升級前備份數據,準備回滾方案。
十八、常見問題與解決方案
1. 性能問題排查
- 慢查詢分析:使用
db.currentOp()
和慢查詢日志定位問題查詢。 - 索引缺失:檢查查詢是否使用索引,
explain()
分析執行計劃。 - 鎖競爭:查看
db.serverStatus().locks
,優化寫入頻率或分片。
2. 磁盤空間問題
- WiredTiger 預分配:使用
db.repairDatabase()
回收未使用空間。 - 刪除過期數據:定期刪除不再需要的歷史數據,或使用 TTL 索引。
- 分片擴容:當單個分片數據量過大時,添加新分片并重新平衡數據。
3. 副本集異常
- 選舉失敗:確保多數節點可用(如 3 節點副本集至少 2 節點在線)。
- 數據不一致:使用
rs.syncFrom("primaryHost")
手動同步數據。 - 仲裁節點配置:奇數個節點或添加仲裁節點避免腦裂。
4. 事務相關問題
- 事務超時:優化事務內操作,減少執行時間或增加
maxTransactionTimeMS
。 - 并發沖突:使用樂觀鎖(如版本號字段)或調整隔離級別。