[TOC]
基本信息
MongoDB 是一个 开源的 NoSQL 数据库,用 JSON 风格的文档来存储数据,而不是传统关系型数据库的表和行。
主要特点
文档型存储
无固定模式(Schema-less)
- 同一个集合(collection)里的文档结构可以不同,方便灵活扩展。
高扩展性
- 支持 分片(Sharding) 和 副本集(Replica Set),可以水平扩展和高可用。
查询功能强大
- 支持丰富的查询语法、聚合管道(Aggregation Pipeline)、地理位置查询等。
适合大数据和快速开发
- 常用于日志存储、实时分析、内容管理、物联网等场景。
基本概念对比(与 MySQL 类比)
MySQL |
MongoDB |
数据库 (Database) |
数据库 (Database) |
表 (Table) |
集合 (Collection) |
行 (Row) |
文档 (Document) |
列 (Column) |
字段 (Field) |
简单操作示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mongo
use mydb
db.users.insert({name: "Alice", age: 25})
db.users.find({age: {$gt: 20}})
db.users.update({name: "Alice"}, {$set: {age: 26}})
db.users.remove({name: "Alice"})
|
我给你按清单的方式整理一下 MongoDB 的 优缺点 和 应用场景,方便快速理解。
MongoDB 的 优缺点 和 应用场景
优点
- 灵活的数据结构
- 文档型存储,直观易读
- 数据以 JSON/BSON 格式保存,前后端交互方便。
- 高可扩展性
- 分片(Sharding)支持水平扩展,适合海量数据。
- 高可用性
- 副本集(Replica Set)保证数据冗余和自动故障切换。
- 查询和聚合功能强
- 开发效率高
缺点
- 事务支持不如关系型数据库
- 虽然 4.0 以后支持多文档事务,但性能不如 MySQL。
- 数据占用空间较大
- BSON 比 JSON 更占空间,存储成本可能增加。
- 过度灵活可能导致数据不规范
- 复杂关联查询性能差
- 内存占用高
典型应用场景
- 内容管理系统(CMS)
- 大数据实时分析
- 物联网(IoT)数据存储
- 地理位置应用
- 电商平台
- 游戏后台
- 社交平台
我建议如果你要存储 结构多变、读写频繁、数据量大 的内容,MongoDB 很合适;
如果你要 事务性强、结构固定、数据关系复杂,MySQL 会更好。
如果你需要,我可以帮你做一份 MongoDB vs MySQL 应用场景对比表,这样你一眼就能判断该用哪个。
docker部署
准备工作
准备配置文件与目录结构

./conf/mongod.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| storage: dbPath: /data/db
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log
net: port: 27017 bindIp: 0.0.0.0
processManagement: fork: false timeZoneInfo: /usr/share/zoneinfo
security: authorization: enabled
|
运行 MongoDB 容器
1 2 3 4 5 6 7 8 9 10 11
| docker run -d \ --name mongodb \ -p 27017:27017 \ -v /data/soft/mongo/mongo-1/data:/data/db \ -v /data/soft/mongo/mongo-1/conf/mongod.conf:/etc/mongod.conf \ -v /data/soft/mongo/mongo-1/logs:/var/log/mongodb \ -e MONGO_INITDB_ROOT_USERNAME=admin \ -e MONGO_INITDB_ROOT_PASSWORD=123456 \ -e TZ=Asia/Shanghai mongo:latest \ --config /etc/mongod.conf
|
参数说明:
--name mongodb
:容器名称
-p 27017:27017
:映射端口
-v /root/mongo/data:/data/db
:持久化数据到宿主机
-e MONGO_INITDB_ROOT_USERNAME
:管理员用户名
-e MONGO_INITDB_ROOT_PASSWORD
:管理员密码
mongo:latest
:镜像名
验证容器运行

连接 MongoDB
进入容器:
1
| docker exec -it mongodb mongosh -u admin -p 123456
|
或者在宿主机直接用客户端连接:
1
| mongodb://admin:123456@<宿主机IP>:27017
|
使用python测试
需要安装 pymongo库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from pymongo import MongoClient
uri = "mongodb://admin:123456@192.168.72.11:27017/mydb?authSource=admin"
client = MongoClient(uri)
db = client["regendb"]
users = db["users"]
for user in users.find(): print(user)
users.insert_one({"name": "regen", "age": 25})
print(users.find_one({"name": "Alice"}))
|

一键安装脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #!/bin/bash set -e
IMAGE_FILE="/resources/mongo7.0.6.tar" IMAGE_NAME="mongo:7.0.6" CONTAINER_NAME="mongodb" MONGO_PORT=27017 MONGO_USER="admin" MONGO_PASSWORD="Z3ACxCMS" TZ="Asia/Shanghai"
BASE_DIR="/data/soft/mongo" DATA_DIR="$BASE_DIR/data" CONF_DIR="$BASE_DIR/conf" LOGS_DIR="$BASE_DIR/logs"
echo "创建目录..." mkdir -p "$DATA_DIR" "$CONF_DIR" "$LOGS_DIR"
chown -R 999:999 "$LOGS_DIR"
if docker pull "$IMAGE_NAME"; then echo "镜像 $IMAGE_NAME 拉取成功,跳过导入" else echo "镜像 $IMAGE_NAME 拉取失败,尝试导入本地镜像 $IMAGE_FILE ..." if docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then echo "镜像 $IMAGE_NAME 已存在,跳过导入" else LOADED_IMAGE=$(docker load -i "$IMAGE_FILE" | awk -F': ' '/Loaded image:/ {print $2}') echo "加载完成,原始镜像: $LOADED_IMAGE"
docker tag "$LOADED_IMAGE" "$IMAGE_NAME" echo "镜像已重命名为 $IMAGE_NAME" fi fi
CONF_FILE="$CONF_DIR/mongod.conf" echo "创建默认配置文件 $CONF_FILE ..." cat > "$CONF_FILE" <<EOF storage: dbPath: /data/db
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log
net: port: $MONGO_PORT bindIp: 0.0.0.0
processManagement: fork: false timeZoneInfo: /usr/share/zoneinfo
security: authorization: enabled EOF
echo "启动 MongoDB 容器..." CONTAINER_ID=$(docker run -d \ --name "$CONTAINER_NAME" \ --restart=unless-stopped \ -p $MONGO_PORT:27017 \ -v "$DATA_DIR":/data/db \ -v "$CONF_FILE":/etc/mongod.conf \ -v "$LOGS_DIR":/var/log/mongodb \ -e MONGO_INITDB_ROOT_USERNAME="$MONGO_USER" \ -e MONGO_INITDB_ROOT_PASSWORD="$MONGO_PASSWORD" \ -e TZ="$TZ" \ $IMAGE_NAME \ --config /etc/mongod.conf) || { echo "容器启动失败!请检查配置或镜像" exit 1 }
if [ "$(docker ps -q -f id=$CONTAINER_ID)" ]; then echo "MongoDB 容器已启动,容器名:$CONTAINER_NAME" docker ps --filter "id=$CONTAINER_ID" else echo "MongoDB 容器启动失败,请查看日志:docker logs $CONTAINER_NAME" exit 1 fi
|
宿主机安装
包管理器安装
1
| sudo dnf install -y mongodb-org
|
离线包安装
准备好离线包
1 2
| dnf download --resolve mongodb-org
|
scp或者xftp复制到某个文件夹后
配置文件(可选)
修改端口绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log
storage: dbPath: /var/lib/mongo journal: enabled: true
processManagement: timeZoneInfo: /usr/share/zoneinfo
net: port: 27017 bindIp: 0.0.0.0
|
启动
1 2 3 4
| sudo systemctl start mongod sudo systemctl enable mongod sudo systemctl status mongod
|
初始化
1 2 3 4 5 6 7
| mongosh use admin db.createUser({ user: "admin", pwd: "123456", roles: [ { role: "root", db: "admin" } ] })
|
一键安装脚本
需要提前准备好安装包到对应的目录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #!/bin/bash
# ============================ # MongoDB 离线安装脚本 # ============================ #
# 1. 离线安装 MongoDB RPM 包 # 2. 自动生成或修改默认配置文件 # 3. 修改 bindIp 为 0.0.0.0,使外部可访问 # 4. 创建数据目录和日志目录,并设置权限 # 5. 启动 MongoDB 服务并启用开机自启 # 6. 创建管理员账号及密码 #
# - 无网络环境下,需要离线安装 MongoDB # - Linux 系统使用 DNF/YUM 包管理的环境(如 CentOS 8 / RHEL 8 / Fedora) #
# - 已将 MongoDB RPM 包放在 /data/resources/mongo 目录 # - 有 sudo 权限 #
# 注意事项: # - 如果管理员账号已存在,会报错 # - 数据目录默认 /var/lib/mongo,日志目录默认 /var/log/mongodb # - 可根据需要修改端口和管理员账号密码变量 #
# 1. 将脚本放在任意目录,例如 /scripts/local-install-mongo.sh # 2. 修改顶部变量 MONGO_RPM_DIR、ADMIN_USER、ADMIN_PASS、PORT # 3. 执行:sudo bash /scripts/local-install-mongo.sh
set -e
# 配置变量 MONGO_RPM_DIR="/data/resources/mongo" CONF_FILE="/etc/mongod.conf" ADMIN_USER="admin" ADMIN_PASS="123456" PORT=27017
echo "===========================" echo "MongoDB 离线安装脚本-开始" echo "==========================="
# 1️⃣ 安装 RPM 包 echo "安装 MongoDB RPM 包..." sudo dnf install -y $MONGO_RPM_DIR/*.rpm
# 2️⃣ 修改配置文件 echo "配置 mongod.conf..." if [ ! -f "$CONF_FILE" ]; then echo "mongod.conf 不存在,创建默认配置..." cat > "$CONF_FILE" <<EOF storage: dbPath: /var/lib/mongo
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log
net: port: $PORT bindIp: 127.0.0.1
processManagement: fork: true timeZoneInfo: /usr/share/zoneinfo
security: authorization: enabled EOF fi
# 修改 bindIp 为 0.0.0.0 sed -i "s/bindIp:.*/bindIp: 0.0.0.0/" "$CONF_FILE"
# 3️⃣ 确保数据目录和日志目录存在且权限正确 DATA_DIR=$(grep 'dbPath' $CONF_FILE | awk '{print $2}') LOG_FILE=$(grep 'path:' $CONF_FILE | grep mongodb | awk '{print $2}') LOG_DIR=$(dirname "$LOG_FILE")
mkdir -p "$DATA_DIR" "$LOG_DIR" chown -R mongod:mongod "$DATA_DIR" "$LOG_DIR" chmod 700 "$DATA_DIR" chmod 755 "$LOG_DIR"
# 4️⃣ 启动 MongoDB 服务 echo "启动 MongoDB..." sudo systemctl enable mongod sudo systemctl start mongod
# 等待服务启动 sleep 5
# 5️⃣ 创建管理员账号 echo "创建管理员账号 $ADMIN_USER..." mongo --eval "db.getSiblingDB('admin').createUser({user: '$ADMIN_USER', pwd: '$ADMIN_PASS', roles:[{role:'root', db:'admin'}]});"
echo "MongoDB 安装完成,管理员账号: $ADMIN_USER 密码: $ADMIN_PASS" echo "默认端口: $PORT, 监听所有 IP: 0.0.0.0" echo "可以使用: sudo systemctl status mongod 查看服务状态"
|


数据备份与恢复
mongo数据库备份分析
1. 早期版本 (MongoDB 2.x~3.6)
- 用户信息可以存储在每个数据库内部,也就是
db.system.users
。
- 用户只对所在数据库有权限。
- 认证数据库默认就是用户所在数据库。
例如:
1 2
| use test db.createUser({user: "alice", pwd: "123", roles: ["readWrite"]})
|
这时用户 alice
存储在 test.system.users
。
2. 现代版本 (MongoDB 4.x~7.x)
- 用户统一存储在
admin
数据库中(默认)。
- MongoDB 使用 “全局用户认证机制”,所有用户和角色信息集中存储在
admin.system.users
。
- 这样管理更集中、权限更统一,也便于跨数据库授权。
例如:
1 2
| use admin db.createUser({user: "admin", pwd: "123", roles: ["root"]})
|
然后可以给其他数据库授予权限,不必在每个数据库中单独创建用户。
早期版本备份用户:
1
| mongodump --db test --collection system.users --out /tmp/backup
|
恢复:
1 2
| mongorestore --db test --collection system.users /tmp/backup/test/system.users.bson
|
全备份示例
1 2 3 4 5
| mkdir -p /tmp/backup
mongodump -u admin --password 123456 --authenticationDatabase admin --out /tmp/backup
|
- 默认会连接本地 27017
- 所有数据库会导出到
/tmp/backup
,每个数据库生成一个文件夹,每个集合生成 .bson
和 .metadata.json
文件。
备份单个数据库
1 2
| mongodump -u admin -p 123456 --authenticationDatabase admin -d regen --out /tmp/backup
|
容器外备份(宿主机访问容器 MongoDB)
如果你在宿主机操作,假设容器映射端口 27017:
1 2 3
| mkdir -p /root/mongo_backup
mongodump -h 127.0.0.1 -p 27017 -u admin --password 123456 --authenticationDatabase admin --out /tmp/backup
|
/tmp/backup
→ 宿主机存储路径
- 会生成类似:
1 2 3 4 5 6
| /root/mongo_backup/ ├── admin/ ├── config/ ├── local/ ├── mydb/ └── otherdb/
|
还原所有数据库
也包括之前的用户认证信息。
如果要恢复全部数据库:
1
| mongorestore -u admin --password 123456 --authenticationDatabase admin /root/backup
|
1
| mongorestore --drop -u admin --password 123456 --authenticationDatabase admin /root/backup
|
- 导出单个数据库 →
--db mydb
- 导出全部数据库 → 不加
--db
- 容器内操作简单,容器外操作需要指定 host/port
- 挂载宿主机目录可以持久化备份
mongo基础
1. 数据库相关
功能 |
命令 |
显示所有数据库 |
show dbs |
切换数据库(不存在会自动创建) |
use mydb |
查看当前数据库 |
db |
删除当前数据库 |
db.dropDatabase() |
2. 集合(表)相关
功能 |
命令 |
显示所有集合 |
show collections |
创建集合 |
db.createCollection("users") |
删除集合 |
db.users.drop() |
3. 数据(文档)操作
插入
1 2 3 4 5
| db.users.insertOne({name: "Alice", age: 25}) db.users.insertMany([ {name: "Bob", age: 30}, {name: "Charlie", age: 28} ])
|
查询
1 2 3 4 5
| db.users.find() db.users.find().pretty() db.users.find({name: "Alice"}) db.users.find({age: {$gt: 25}}) db.users.find({}, {name: 1, _id: 0})
|
更新
1 2 3 4 5 6 7 8 9
| db.users.updateOne( {name: "Alice"}, {$set: {age: 26}} )
db.users.updateMany( {age: {$gt: 25}}, {$set: {status: "active"}} )
|
删除
1 2
| db.users.deleteOne({name: "Bob"}) db.users.deleteMany({age: {$lt: 20}})
|
4. 索引
1 2 3
| db.users.createIndex({name: 1}) db.users.getIndexes() db.users.dropIndex("name_1")
|
5. 用户与权限
1 2 3 4 5 6 7 8 9 10
| use admin db.createUser({ user: "admin", pwd: "123456", roles: [{role: "root", db: "admin"}] })
show users
|
问题
时区
配置文件里的时区项不能随意修改timeZoneInfo: /usr/share/zoneinfo
如果是docker部署需要在run的时候使用 -e TZ=Asia/Shanghai
,如果是宿主机则会(还不清楚)…
不管是docker还是宿主机,这项配置改动了都可能起不来。
Docker 容器中推荐用 -e TZ
方式设置时区,而不是修改 mongod.conf
。
配置文件修改 timeZoneInfo
只在特殊场景下使用,并且容易出错。