Skip to content
On this page

MongoDB 基础概念

MongoDB是一个面向文档的NoSQL数据库,它使用文档(documents)来存储数据,这些文档采用BSON(Binary JSON)格式。了解MongoDB的基础概念对于有效使用这个数据库至关重要。

文档(Document)

文档是MongoDB中的基本数据单元,类似于关系数据库中的行。文档使用键值对存储数据,格式类似于JSON。

文档结构

json
{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "name": "张三",
  "age": 25,
  "email": "zhangsan@example.com",
  "address": {
    "street": "中山路123号",
    "city": "北京",
    "zipcode": "100000"
  },
  "hobbies": ["读书", "游泳", "编程"],
  "isActive": true,
  "registeredDate": ISODate("2023-01-01T00:00:00Z")
}

文档特点

  • 动态模式:同一集合中的文档可以有不同的字段
  • 嵌套结构:文档可以包含子文档和数组
  • 唯一标识符:每个文档都有一个唯一的_id字段
  • BSON类型:支持丰富的数据类型

_id字段

每个文档都有一个名为_id的主键字段,其值在集合中必须唯一:

javascript
// 自动生成的ObjectId
_id: ObjectId("507f1f77bcf86cd799439011")

// 自定义_id值
_id: "custom-id-123"
_id: 12345
_id: UUID("5e8d4e8d-1b3a-4c2d-8e9f-0a1b2c3d4e5f")

集合(Collection)

集合是文档的分组,类似于关系数据库中的表。集合具有以下特点:

集合特征

  • 动态模式:集合中的文档可以有不同的结构
  • 命名空间:集合名称在数据库中必须唯一
  • 自动创建:当第一次插入文档时,集合会被自动创建
  • 无模式定义:不需要预先定义集合的结构

集合命名规则

  • 集合名称不能以"system."开头
  • 集合名称不能包含保留字符"$"
  • 集合名称不能为空字符串

示例

javascript
// 创建集合并插入文档
db.users.insertOne({
  name: "王五",
  email: "wangwu@example.com"
});

db.products.insertMany([
  { name: "笔记本电脑", price: 5999, category: "电子产品" },
  { name: "鼠标", price: 99, category: "电子产品" }
]);

数据库(Database)

数据库是集合的容器,MongoDB支持多个数据库。

数据库特点

  • 物理隔离:不同数据库的数据文件相互隔离
  • 逻辑分组:用于组织相关集合
  • 权限控制:可以在数据库级别设置权限

常用数据库

javascript
// 系统数据库
admin       // 根用户、角色和特权
local       // 分片和副本集配置
config      // 分片集群配置

// 用户数据库
myApp       // 应用程序数据库
test        // 测试数据库

BSON数据类型

MongoDB使用BSON(Binary JSON)格式存储文档。BSON扩展了JSON,支持更多数据类型:

基本类型

类型JSONBSON示例
字符串StringString"hello"
整数NumberInt32/Int6442
双精度NumberDouble3.14
布尔值BooleanBooleantrue/false
数组ArrayArray[1, 2, 3]
文档ObjectObject

特殊类型

类型BSON描述示例
ObjectIdObjectId文档唯一标识符ObjectId("...")
日期DateUTC时间ISODate("...")
正则表达式RegExp模式匹配/pattern/i
nullNull空值null
二进制数据BinData二进制数据BinData(...)
代码CodeJavaScript代码function(){}
符号Symbol特定语言字符串Symbol("str")

命名空间

命名空间是数据库名称和集合名称的组合,格式为database.collection

javascript
// 命名空间示例
myApp.users           // myApp数据库中的users集合
blog.posts            // blog数据库中的posts集合
shop.products         // shop数据库中的products集合

索引(Index)

索引提高了查询性能,类似于书籍的目录。

索引类型

  • 单字段索引:基于单个字段的索引
  • 复合索引:基于多个字段的索引
  • 多键索引:基于数组字段的索引
  • 文本索引:用于文本搜索
  • 地理空间索引:用于地理位置查询

创建索引

javascript
// 单字段索引
db.users.createIndex({ email: 1 })

// 复合索引
db.orders.createIndex({ userId: 1, orderDate: -1 })

// 唯一索引
db.users.createIndex({ email: 1 }, { unique: true })

GridFS

GridFS是MongoDB用来存储大型文件的规范,将文件分割成较小的块进行存储。

GridFS特点

  • 存储大于16MB的文件
  • 文件被分割成255KB的块
  • 提供文件元数据存储
  • 支持断点续传

原子性和事务

单文档原子性

MongoDB保证单个文档的所有写操作都是原子的。

多文档事务

从MongoDB 4.0开始支持多文档ACID事务:

javascript
// 4.0+版本的多文档事务
const session = client.startSession();
session.withTransaction(async () => {
  await db.accounts.updateOne(
    { name: "张三" },
    { $inc: { balance: -100 } }
  );
  
  await db.accounts.updateOne(
    { name: "李四" },
    { $inc: { balance: 100 } }
  );
});

副本集(Replica Set)

副本集是一组维护相同数据集的mongod实例,提供冗余和高可用性。

副本集组成

  • 主节点(Primary):处理所有写操作
  • 从节点(Secondary):复制主节点的数据
  • 仲裁节点(Arbiter):参与选举,不存储数据

分片(Sharding)

分片是将数据分布在多个机器上的方法,用于处理大量数据和高吞吐量操作。

分片组件

  • 分片(Shard):存储数据子集
  • 配置服务器(Config Servers):存储集群元数据
  • mongos:查询路由器

连接池

MongoDB驱动程序使用连接池来管理与数据库的连接:

javascript
const options = {
  maxPoolSize: 10,      // 最大连接数
  minPoolSize: 5,       // 最小连接数
  maxIdleTimeMS: 30000, // 最大空闲时间
  serverSelectionTimeoutMS: 5000, // 服务器选择超时
  socketTimeoutMS: 45000 // 套接字超时
};

总结

MongoDB的基础概念构成了理解和使用这个数据库的基石。文档、集合和数据库是MongoDB数据模型的核心组件,而索引、原子性、副本集和分片等概念则是构建高性能、高可用性应用的关键要素。掌握这些概念有助于更好地设计MongoDB应用程序。