💈MongoDB 总结

type
status
date
slug
summary
tags
category
icon
password
Blocked by
Blocking
AI summary
 

MongoDB是什么

MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常流行的 文档类型数据库
在高负载的情况下,MongoDB 天然支持水平扩展和高可用,可以很方便地添加更多的节点/实例,以保证服务性能和可用性。在许多场景下,MongoDB 可以用于代替传统的关系型数据库或键/值存储方式,皆在为 Web 应用提供可扩展的高可用高性能数据存储解决方案。
 

MongoDB的存储结构

  • 文档(Document):MongoDB 中最基本的单元,由 BSON 键值对(key-value)组成,类似于关系型数据库中的行(Row)。
  • 集合(Collection):一个集合可以包含多个文档,类似于关系型数据库中的表(Table)。
  • 数据库(Database):一个数据库中可以包含多个集合,可以在 MongoDB 中创建多个数据库,类似于关系型数据库中的数据库(Database)。

SQL 与 MongoDB 常见术语对比

SQL
MongoDB
表(Table)
集合(Collection)
行(Row)
文档(Document)
列(Col)
字段(Field)
主键(Primary Key)
对象 ID(Objectid)
索引(Index)
索引(Index)
嵌套表(Embedded Table)
嵌入式文档(Embedded Document)
数组(Array)
数组(Array)

MongoDB的存储引擎

查看引擎
MongoDB的存储引擎有很多种,WiredTiger 是目前最常用的(默认)存储引擎,提供了高性能、压缩和事务支持。
  • 支持文档级别的并发控制(Document-Level Concurrency),允许多个操作同时修改集合中的不同文档,提高了并发性能。
  • 支持压缩(Compression),可以减少磁盘空间占用,支持 Snappy 和 Zlib 压缩算法。
  • 支持高效的缓存管理,使用内存缓存(Cache)来加速数据访问。
  • 支持事务(Transactions),从 MongoDB 4.0 开始支持多文档事务。
 

简单使用

使用docker-compose 搭建环境

 
 
 
notion image
 

基础的增删改查

  • 创建集合db.createCollection("collectionName")
  • 插入数据db.collectionName.insertOne() 或 db.collectionName.insertMany()
  • 查询数据db.collectionName.find()
  • 更新数据:db.collection.updateOne(filter, update, options)db.collection.updateMany(filter, update, options)
    • filter:用于查找文档的查询条件。
    • update:指定更新操作的文档或更新操作符。
    • options:可选参数对象,如 upsertarrayFilters 等
  • 删除数据db.collectionName.deleteOne() 或 db.collectionName.deleteMany()
  • 删除集合db.collectionName.drop()
  • sort表示排序,1标识升序,-1标识降序
 
 
 

MongoDB的聚合操作

由多个阶段组成,每个阶段在文档通过管道时转换文档。每个阶段接收前一个阶段的输出,进一步处理数据,并将其作为输入数据发送到下一个阶段。
notion image

常用阶段操作符

操作符
简述
$match
匹配操作符,用于对文档集合进行筛选
$project
投射操作符,用于重构每一个文档的字段,可以提取字段,重命名字段,甚至可以对原有字段进行操作后新增字段
$sort
排序操作符,用于根据一个或多个字段对文档进行排序
$limit
限制操作符,用于限制返回文档的数量
$skip
跳过操作符,用于跳过指定数量的文档
$count
统计操作符,用于统计文档的数量
$group
分组操作符,用于对文档集合进行分组
$unwind
拆分操作符,用于将数组中的每一个值拆分为单独的文档
$lookup
连接操作符,用于连接同一个数据库中另一个集合,并获取指定的文档,类似于 populate

语法格式

 

实例

group 分组查询

 

bucket 同组数据汇聚

unwind 将数组展开

lookup实现关联查询

也可以搭配$unwind将userOrders数组拆分

MongoDB 架构

Master-Slave

Master-Slave 由主从角色构成:
Master ( 主 )
可读可写,当数据有修改的时候,会将 Oplog 同步到所有连接的Salve 上去
Slave ( 从 )
只读,所有的 Slave 从 Master 同步数据,从节点与从节点之间不感知
notion image
 

Replica Set(副本集模式)

  • 数据多副本,在故障的时候,可以使用完的副本恢复服务。注意:这里是故障自动恢复
  • 读写分离,读的请求分流到副本上,减轻主(Primary)的读压力;
  • 节点直接互有心跳,可以感知集群的整体状态;
    • notion image

Sharding

notion image
MongoDB 的 sharding 是一种水平扩展方法,允许跨多台机器分布数据。sharding 架构由以下几个组件组成:
  • mongos: 这是查询路由器,充当应用程序和分片集群之间的接口。客户端连接到 mongos,而不是直接连接到各个分片
  • Config Servers
    • config Servers 维护着集群元数据,包括 Chunk 到 Shard 的映射关系
    • 这些映射存储在 Config Server 的 config.chunks 集合中
    • 每个 Chunk 记录包含其范围(minmax值)和所属的 Shard ID
  • Shard: 每个 shard 是存储部分数据的独立 MongoDB 实例或 replica set。实际数据存储在这里
  • 分片键(Shard Key): 用于在分片间分配数据的字段。MongoDB 使用分片键决定数据属于哪个分片。
 

工作原理

  • 数据分区: 基于分片键,将集合拆分为块(chunks)。
  • 分布式查询: mongos 会将查询路由到适当的分片。
  • 负载平衡: MongoDB 自动在分片之间平衡数据,确保数据均匀分布。
  • 自动故障转移: 每个分片通常是一个 replica set,提供高可用性。
 

Sharding 与 Replica Sets 对比

相似点
  • 都提供高可用性和故障转移功能
  • 都支持自动恢复
  • 都使用 MongoDB 的原生复制机制
区别
特性
Sharding
Replica Sets
主要目的
水平扩展,提高性能和存储容量
数据冗余和高可用性
数据分布
数据分布在多个分片上
完整数据集复制到所有节点
扩展方式
水平扩展(更多机器)
主要是垂直扩展(更好的硬件)
架构复杂性
较复杂,需要维护更多组件
相对简单
适用场景
大数据量,高并发
中小规模数据,需要冗余
查询路由
通过 mongos 路由
直接连接到 primary 或 secondary
管理开销
较高
较低

MongoDB的事物

MongoDB 事务遵循 ACID 属性(原子性、一致性、隔离性和持久性),允许对多个文档的操作作为一个单元执行,要么全部成功,要么全部失败。

支持的操作

事务中支持以下操作:
  • CRUD 操作 (创建、读取、更新、删除)
  • 批量写入操作
  • 查找和修改操作

不支持的操作

事务中不支持:
  • 创建/删除集合
  • 创建/删除索引
  • 删除数据库
  • 聚合 $out 和 $merge 阶段

事务配置参数

读关注 (Read Concern)

定义事务中读操作返回的数据的一致性级别:
  • "local": 返回最新的数据,无需确认是否已被多数节点确认
  • "majority": 返回已被大多数节点确认的数据
  • "snapshot": 返回同一时间点的多文档快照(事务中推荐)

写关注 (Write Concern)

定义写操作的确认要求:
  • { w: 1 }: 主节点确认
  • { w: "majority" }: 大多数节点确认(事务中推荐)
  • { j: true }: 写入操作必须写入到磁盘日志

读偏好 (Read Preference)

定义从哪些节点读取数据:
  • "primary": 从主节点读取(事务中必须)
 

事务限制与最佳实践

限制

  1. 时间限制: 事务必须在 60 秒内完成(可配置但不推荐超过默认值)
  1. 大小限制: 单个事务中的操作不能超过 16MB
  1. 资源锁: 过长的事务可能会导致资源锁定
  1. 性能影响: 事务会对性能产生一定影响

最佳实践

  1. 保持事务简短: 尽量减少事务中的操作数量和持续时间
  1. 避免大事务: 不要在一个事务中处理太多文档
  1. 合理设置超时: 根据业务需求设置适当的超时时间
  1. 异常处理: 始终包含错误处理和回滚逻辑
  1. 会话复用: 在可能的情况下复用会话以提高性能
  1. 索引优化: 确保事务中使用的查询有适当的索引支持
 

MongoDB的索引

查看索引
创建索引
删除索引

使用Golang SDK

 
code

需要注意的点

查询时

处理 mongo.ErrNoDocuments 错误,表示没有找到文档

更新时

使用$set 更新指定字段,避免覆盖整个文档
 

Reference

 
Prev
kafka学习笔记
Next
Golang map
Loading...
Article List