- 1. MongoDB学习笔记
- 2. 核心知识总结
- 3. 参考资料
MongoDB is a source-available cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas.
MongoDB学习笔记
一、MongoDB基础概念
1.1 什么是MongoDB
MongoDB是一个基于分布式文件存储的文档型数据库,由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
核心特点:
- 面向文档存储(Document-Oriented)
- 高性能(High Performance)
- 高可用性(High Availability)
- 易扩展性(Easy Scalability)
- 丰富的查询语言(Rich Query Language)
1.2 MongoDB与关系型数据库对比
| SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
|---|---|---|
| database | database | 数据库 |
| table | collection | 数据库表/集合 |
| row | document | 数据记录行/文档 |
| column | field | 数据字段/域 |
| index | index | 索引 |
| table joins | embedded documents | 表连接(MongoDB不支持)/嵌入文档 |
| primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
示例对比:
1 | -- MySQL |
1 | // MongoDB |
1.3 MongoDB数据类型
| 数据类型 | 描述 | 示例 |
|---|---|---|
| String | 字符串,UTF-8编码 | “hello world” |
| Integer | 整型数值 | 123, -456 |
| Double | 双精度浮点值 | 3.14, -2.5 |
| Boolean | 布尔值 | true, false |
| Array | 数组或列表 | [1, 2, 3] |
| Object | 嵌入式文档 | {name: “张三”} |
| Null | 空值 | null |
| Date | 日期时间 | ISODate(“2024-01-01”) |
| ObjectId | 对象ID,文档的唯一标识 | ObjectId(“507f1f77bcf86cd799439011”) |
| Binary Data | 二进制数据 | 图片、文件等 |
| Code | JavaScript代码 | function() { return 1; } |
| Regular Expression | 正则表达式 | /pattern/i |
二、MongoDB安装与配置
2.1 Docker方式安装(推荐)
1 | # 拉取MongoDB镜像 |
2.2 Linux系统安装
1 | # Ubuntu/Debian |
2.3 MongoDB配置文件
1 | # /etc/mongod.conf |
三、MongoDB基本操作(CRUD)
3.1 数据库操作
1 | // 查看所有数据库 |
3.2 集合操作
1 | // 创建集合 |
3.3 文档插入(Create)
1 | // 插入单个文档 |
3.4 文档查询(Read)
1 | // 查询所有文档 |
3.5 文档更新(Update)
1 | // 更新单个文档 |
3.6 文档删除(Delete)
1 | // 删除单个文档 |
四、MongoDB高级查询
4.1 聚合查询(Aggregation)
1 | // 基础聚合 |
4.2 索引优化
1 | // 创建索引 |
五、MongoDB副本集(Replica Set)
5.1 副本集概念
副本集是一组维护相同数据集的MongoDB服务器。副本集提供了数据冗余和高可用性,是生产部署的基础。
副本集角色:
- Primary(主节点):接收所有写操作
- Secondary(从节点):复制主节点的操作日志(oplog)
- Arbiter(仲裁节点):不存储数据,仅参与选举投票
5.2 副本集配置
1 | # 1. 启动三个MongoDB实例 |
1 | // 初始化副本集 |
5.3 副本集故障转移测试
1 | # 模拟主节点宕机 |
六、MongoDB分片集群(Sharding)
6.1 分片概念
分片是MongoDB的数据分布式存储方案,用于处理大量数据和高吞吐量操作。
分片集群组件:
- Config Servers(配置服务器):存储集群元数据
- Shard(分片服务器):存储实际数据
- Mongos(路由服务器):查询路由器
6.2 分片集群搭建
1 | # 1. 启动配置服务器(至少3个) |
七、MongoDB安全配置
7.1 用户权限管理
1 | // 创建管理员用户 |
7.2 网络安全配置
1 | # mongod.conf |
八、MongoDB性能优化
8.1 查询优化
1 | // 使用explain分析查询 |
8.2 写入优化
1 | // 批量插入 |
8.3 内存和存储优化
1 | // 查看内存使用 |
核心知识总结
一、MongoDB核心概念速查表
1.1 MongoDB vs SQL术语映射
| MongoDB | SQL | 说明 |
|---|---|---|
| Database | Database | 数据库 |
| Collection | Table | 集合/表 |
| Document | Row | 文档/行 |
| Field | Column | 字段/列 |
| Embedded Document | Table Join | 内嵌文档/表连接 |
| _id | Primary Key | 主键 |
| Index | Index | 索引 |
1.2 CRUD操作速查
| 操作 | SQL | MongoDB |
|---|---|---|
| 插入 | INSERT INTO users VALUES (...) |
db.users.insertOne({...}) |
| 查询 | SELECT * FROM users WHERE age > 25 |
db.users.find({age: {$gt: 25}}) |
| 更新 | UPDATE users SET age = 26 WHERE name = '张三' |
db.users.updateOne({name: "张三"}, {$set: {age: 26}}) |
| 删除 | DELETE FROM users WHERE age < 18 |
db.users.deleteMany({age: {$lt: 18}}) |
| 统计 | SELECT COUNT(*) FROM users |
db.users.countDocuments() |
| 排序 | SELECT * FROM users ORDER BY age DESC |
db.users.find().sort({age: -1}) |
| 分页 | SELECT * FROM users LIMIT 10 OFFSET 20 |
db.users.find().skip(20).limit(10) |
二、查询操作符完整清单
2.1 比较操作符
1 | // 相等性 |
2.2 逻辑操作符
1 | // AND |
2.3 元素操作符
1 | {field: {$exists: true}} // 字段存在 |
2.4 数组操作符
1 | {tags: {$all: ["tag1", "tag2"]}} // 包含所有元素 |
2.5 更新操作符
1 | // 字段更新 |
三、索引策略与最佳实践
3.1 索引类型总结
| 索引类型 | 创建语法 | 适用场景 |
|---|---|---|
| 单字段索引 | db.col.createIndex({field: 1}) |
单字段查询、排序 |
| 复合索引 | db.col.createIndex({f1: 1, f2: -1}) |
多字段组合查询 |
| 多键索引 | db.col.createIndex({tags: 1}) |
数组字段查询 |
| 文本索引 | db.col.createIndex({content: "text"}) |
全文搜索 |
| 哈希索引 | db.col.createIndex({field: "hashed"}) |
分片键、等值查询 |
| 地理空间索引 | db.col.createIndex({loc: "2dsphere"}) |
地理位置查询 |
| TTL索引 | db.col.createIndex({date: 1}, {expireAfterSeconds: 3600}) |
自动过期数据 |
| 唯一索引 | db.col.createIndex({email: 1}, {unique: true}) |
唯一性约束 |
| 部分索引 | db.col.createIndex({f: 1}, {partialFilterExpression: {...}}) |
条件索引 |
| 稀疏索引 | db.col.createIndex({f: 1}, {sparse: true}) |
字段不总是存在 |
3.2 复合索引设计原则(ESR规则)
1 | // ESR: Equality, Sort, Range |
3.3 索引优化建议
何时创建索引:
- 频繁查询的字段
- 排序字段
- 唯一性约束字段
- 外键字段(关联查询)
何时避免索引:
- 数据量很小的集合(<1000文档)
- 写操作远多于读操作
- 字段值重复率很高(如性别)
- 返回结果集占比很大(>30%)
索引监控:
1 | // 查看索引使用情况 |
四、聚合管道实战案例
4.1 常见聚合场景
场景1:销售统计
1 | // 统计每个产品的总销售额和平均价格 |
场景2:用户行为分析
1 | // 按日期统计活跃用户 |
场景3:订单关联查询
1 | // 订单关联用户和产品信息 |
4.2 聚合管道阶段速查
| 阶段 | 说明 | 示例 |
|---|---|---|
| $match | 过滤文档 | {$match: {age: {$gt: 25}}} |
| $group | 分组聚合 | {$group: {_id: "$city", count: {$sum: 1}}} |
| $project | 字段投影 | {$project: {name: 1, age: 1}} |
| $sort | 排序 | {$sort: {age: -1}} |
| $limit | 限制结果数 | {$limit: 10} |
| $skip | 跳过文档 | {$skip: 20} |
| $unwind | 展开数组 | {$unwind: "$tags"} |
| $lookup | 关联查询 | {$lookup: {from: "users", ...}} |
| $out | 输出到集合 | {$out: "result"} |
| $count | 计数 | {$count: "total"} |
| $facet | 多维聚合 | {$facet: {统计1: [...], 统计2: [...]}} |
五、副本集架构详解
5.1 副本集工作原理
graph TB
Client[客户端] --> Primary[主节点Primary]
Primary --> |oplog复制| Secondary1[从节点1]
Primary --> |oplog复制| Secondary2[从节点2]
Primary --> |心跳| Secondary1
Primary --> |心跳| Secondary2
Secondary1 --> |心跳| Secondary2
subgraph 故障转移
A[主节点宕机] --> B[从节点检测]
B --> C[发起选举]
C --> D[多数投票]
D --> E[新主节点产生]
end
5.2 副本集配置参数详解
1 | rs.initiate({ |
5.3 读写策略配置
1 | // 写关注(Write Concern) |
六、分片集群架构实战
6.1 分片键选择策略
| 分片键类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 哈希分片 | 数据分布均匀 | 不支持范围查询 | 随机访问、写入密集 |
| 范围分片 | 支持范围查询 | 可能数据倾斜 | 时间序列、有序数据 |
| 复合分片 | 兼顾均匀和查询 | 配置复杂 | 复杂查询场景 |
分片键选择原则:
1 | // 1. 高基数(Cardinality)- 唯一值多 |
6.2 分片集群监控
1 | // 查看分片状态 |
七、MongoDB性能调优清单
7.1 Schema设计优化
反模式1:过度嵌套
1 | // 不好:嵌套太深 |
反模式2:大数组
1 | // 不好:无限增长的数组 |
7.2 查询优化技巧
1 | // 1. 使用投影减少数据传输 |
7.3 连接池配置
1 | // Node.js驱动示例 |
八、MongoDB监控指标
8.1 关键监控指标
1 | // 1. 服务器状态 |
8.2 性能分析工具
1 | // 1. explain()分析 |
九、生产环境最佳实践
9.1 部署架构建议
1 | # 小规模(<100GB,<10万QPS) |
9.2 备份策略
1 | # 1. mongodump(逻辑备份) |
9.3 安全加固建议
1 | # mongod.conf安全配置 |