Skip to content

MongoDB 集合与数据库

数据库基础

数据库概念

数据库是MongoDB中存储集合的容器,每个数据库都有自己的命名空间和权限控制。MongoDB采用多租户设计,允许在同一实例上运行多个独立的数据库,每个数据库拥有自己的集合、用户和权限。

数据库命名规范

  • 区分大小写:MongoDB数据库名称区分大小写,如"mydb"和"MyDB"是两个不同的数据库
  • 长度限制:数据库名称最大长度为64字节
  • 字符限制:不能包含特殊字符,如空格、点号(.)、$、/、\和\0(空字符)
  • 命名建议:使用有意义、简洁的名称,避免使用保留名称

系统数据库

MongoDB包含以下系统数据库,用于存储系统级别的信息和配置:

  • admin:存储系统级别的权限和配置,包括用户认证信息
  • local:存储本地数据,不参与复制,如副本集的oplog
  • config:存储分片集群的元数据和配置信息
  • test:默认的测试数据库,连接时如果不指定数据库,默认连接到test数据库

集合基础

集合概念

集合是MongoDB中存储文档的容器,类似于关系数据库中的表。与关系数据库不同,MongoDB集合是动态的,不需要预先定义模式,同一集合中的文档可以具有不同的结构。

集合类型

MongoDB支持多种类型的集合,以满足不同的应用场景:

  • 普通集合:默认类型,存储任意结构的文档
  • 固定集合(Capped Collection):有固定大小和先进先出(FIFO)特性,用于存储日志等时序数据
  • 时间序列集合(Time Series Collection):MongoDB 5.0及以上版本支持,专门用于存储和查询时间序列数据
  • 视图集合:基于其他集合的查询结果创建的虚拟集合
  • 桶集合:用于优化时间序列数据的存储和查询性能

集合命名规范

  • 区分大小写:集合名称区分大小写,如"mycollection"和"MyCollection"是两个不同的集合
  • 长度限制:集合名称最大长度为64字节
  • 字符限制:可以包含点号(.),用于组织集合,但不能包含$和\0(空字符)
  • 系统前缀:不能以"system."开头,这是系统集合的保留前缀
  • 命名建议:使用有意义、简洁的名称,建议使用复数形式

数据库与集合管理

数据库管理命令

连接到指定数据库

javascript
use database_name

如果数据库不存在,MongoDB会在首次插入数据时自动创建。

查看当前数据库

javascript
db

删除当前数据库

javascript
db.dropDatabase()

查看所有数据库

javascript
show dbs

注意:只有包含数据的数据库才会显示。

查看数据库统计信息

javascript
db.stats()

返回数据库的大小、文档数量等统计信息。

集合管理命令

创建集合

javascript
db.createCollection("collection_name", options)

常用选项:

  • capped: 布尔值,是否创建固定集合
  • size: 数值,固定集合的最大大小(字节)
  • max: 数值,固定集合的最大文档数
  • validator: 文档,文档验证规则
  • validationLevel: 字符串,验证级别(strict或moderate)
  • validationAction: 字符串,验证失败时的操作(error或warn)

查看当前数据库中的集合

javascript
show collections

javascript
db.getCollectionNames()

删除集合

javascript
db.collection_name.drop()

重命名集合

javascript
db.collection_name.renameCollection("new_collection_name")

查看集合统计信息

javascript
db.collection_name.stats()

返回集合的大小、文档数量、索引信息等统计数据。

命名空间

命名空间概念

命名空间是MongoDB中用于标识数据库和集合的唯一标识符,格式为database_name.collection_name

命名空间限制

  • 长度限制:命名空间最大长度为123字节
  • 组成部分:包括数据库名称、点号(.)和集合名称
  • 开销影响:命名空间的长度会影响存储开销,建议使用简短的名称

文档验证

文档验证概念

文档验证是MongoDB 3.2及以上版本提供的功能,用于验证插入和更新的文档是否符合指定的规则。通过文档验证,可以确保集合中的文档遵循一致的结构。

创建带有验证规则的集合

javascript
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email"],
      properties: {
        name: {
          bsonType: "string",
          description: "姓名必须是字符串"
        },
        email: {
          bsonType: "string",
          pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
          description: "邮箱必须符合正则表达式"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          maximum: 120,
          description: "年龄必须是18到120之间的整数"
        }
      }
    }
  }
});

修改集合的验证规则

javascript
db.runCommand({
  collMod: "users",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email", "phone"],
      properties: {
        name: {
          bsonType: "string"
        },
        email: {
          bsonType: "string",
          pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
        },
        phone: {
          bsonType: "string"
        }
      }
    }
  }
});

固定集合

固定集合概念

固定集合是一种特殊类型的集合,具有固定大小和先进先出(FIFO)特性。当固定集合达到最大大小时,新插入的文档会自动覆盖最早的文档。

固定集合特点

  • 固定大小:创建时必须指定大小和可选的最大文档数
  • FIFO行为:当集合满时,自动覆盖最早的文档
  • 高性能:适合存储日志、事件等时序数据
  • 顺序存储:文档按照插入顺序存储,查询时无需排序
  • 限制:不能删除单个文档,只能删除整个集合

创建固定集合

javascript
db.createCollection("logs", {
  capped: true,
  size: 10485760,  // 10MB
  max: 10000       // 最多10000个文档
});

检查集合是否为固定集合

javascript
db.collection_name.isCapped()

时间序列集合

时间序列集合概念

时间序列集合是MongoDB 5.0及以上版本引入的特性,专门用于存储和查询时间序列数据,如传感器数据、监控指标等。

时间序列集合特点

  • 高效存储:针对时间序列数据进行了优化,减少存储开销
  • 高性能查询:支持高效的时间范围查询和聚合操作
  • 自动过期:支持数据自动过期,基于时间字段
  • 灵活的架构:允许嵌套字段和多维度数据

创建时间序列集合

javascript
db.createCollection("sensor_data", {
  timeseries: {
    timeField: "timestamp",  // 时间字段
    metaField: "metadata",   // 元数据字段(可选)
    granularity: "seconds"    // 时间粒度(seconds, minutes, hours)
  },
  expireAfterSeconds: 3600  // 数据自动过期时间(可选)
});

版本差异

MongoDB 4.0 与 5.0 的差异

功能MongoDB 4.0MongoDB 5.0
时间序列集合不支持支持
文档验证基本支持增强的验证规则
集合统计信息基本统计改进的统计信息,包括更详细的索引数据
分片集合支持支持增强的分片集合支持,提高分片性能
事务支持支持增强的事务支持,提高事务性能

MongoDB 5.0 与 6.0 的差异

功能MongoDB 5.0MongoDB 6.0
向量搜索不支持支持
文档存储格式传统格式改进的存储格式,提高查询性能
集合级加密基本支持增强的集合级加密,支持更多加密算法
时间序列集合支持增强的时间序列集合,支持更灵活的架构
事务支持支持增强的事务支持,提高事务性能

生产实践建议

数据库设计建议

  • 根据业务需求设计数据库结构:避免过度设计,根据实际业务需求设计数据库结构
  • 合理规划数据库数量:避免创建过多的数据库,每个数据库都有自己的开销
  • 使用有意义的名称:数据库和集合名称应该反映其用途,便于理解和维护
  • 考虑数据增长:设计时考虑数据的增长趋势,为未来的扩展做好准备

集合设计建议

  • 根据访问模式设计集合结构:根据查询和写入模式设计集合结构,优化性能
  • 避免单个集合过大:对于大型集合,考虑分片或拆分集合
  • 合理使用嵌入文档:根据访问模式决定是嵌入文档还是使用引用
  • 为集合设置适当的验证规则:使用文档验证确保数据质量

固定集合最佳实践

  • 用于日志和事件数据:固定集合适合存储日志、事件等时序数据
  • 合理设置大小:根据数据量和保留时间设置合适的大小
  • 考虑查询模式:固定集合查询时无需排序,适合按插入顺序查询
  • 避免频繁更新:固定集合不适合频繁更新的场景

时间序列集合最佳实践

  • 用于时间序列数据:时间序列集合适合存储传感器数据、监控指标等时间序列数据
  • 合理设置粒度:根据数据的时间间隔设置合适的粒度
  • 使用元数据字段:合理使用元数据字段,提高查询性能
  • 设置数据过期时间:根据业务需求设置数据自动过期时间

常见问题(FAQ)

Q1: 如何创建数据库?

A1: 在MongoDB中,创建数据库的方法是使用use命令切换到指定数据库,然后向该数据库中插入数据。当首次向数据库中插入数据时,MongoDB会自动创建该数据库。

javascript
use mydb  // 切换到mydb数据库,如果不存在则创建
 db.mycollection.insertOne({ name: "test" })  // 插入数据,触发数据库创建

Q2: 如何创建集合?

A2: 创建集合的方法有两种:

  1. 显式创建:使用db.createCollection()命令显式创建集合
  2. 隐式创建:直接向集合中插入数据,MongoDB会自动创建集合

显式创建示例:

javascript
db.createCollection("mycollection")

隐式创建示例:

javascript
db.mycollection.insertOne({ name: "test" })

Q3: 数据库和集合的区别是什么?

A3: 数据库是集合的容器,而集合是文档的容器。一个MongoDB实例可以包含多个数据库,每个数据库可以包含多个集合,每个集合可以包含多个文档。

Q4: 如何查看数据库的大小?

A4: 可以使用db.stats()命令查看数据库的大小和其他统计信息:

javascript
use mydb
db.stats()

返回结果中的dataSize字段表示数据库中数据的大小,storageSize字段表示实际占用的存储空间大小。

Q5: 如何查看集合的大小?

A5: 可以使用db.collection_name.stats()命令查看集合的大小和其他统计信息:

javascript
db.mycollection.stats()

返回结果中的size字段表示集合中数据的大小,storageSize字段表示实际占用的存储空间大小。

Q6: 什么是固定集合?

A6: 固定集合是一种特殊类型的集合,具有固定大小和先进先出(FIFO)特性。当固定集合达到最大大小时,新插入的文档会自动覆盖最早的文档。固定集合适合存储日志、事件等时序数据。

Q7: 如何创建固定集合?

A7: 创建固定集合时,需要指定capped选项为true,并设置size和可选的max参数:

javascript
db.createCollection("logs", {
  capped: true,
  size: 10485760,  // 10MB
  max: 10000       // 最多10000个文档
});

Q8: 什么是时间序列集合?

A8: 时间序列集合是MongoDB 5.0及以上版本引入的特性,专门用于存储和查询时间序列数据,如传感器数据、监控指标等。时间序列集合针对时间序列数据进行了优化,提供了高效的存储和查询性能。

Q9: 如何创建时间序列集合?

A9: 创建时间序列集合时,需要指定timeseries选项:

javascript
db.createCollection("sensor_data", {
  timeseries: {
    timeField: "timestamp",  // 时间字段
    metaField: "metadata",   // 元数据字段(可选)
    granularity: "seconds"    // 时间粒度
  }
});

Q10: 如何删除数据库?

A10: 可以使用db.dropDatabase()命令删除当前数据库:

javascript
use mydb
db.dropDatabase()

Q11: 如何删除集合?

A11: 可以使用db.collection_name.drop()命令删除指定集合:

javascript
db.mycollection.drop()

Q12: 如何重命名集合?

A12: 可以使用db.collection_name.renameCollection()命令重命名集合:

javascript
db.mycollection.renameCollection("newcollection")

Q13: 数据库和集合的命名规则是什么?

A13:

数据库命名规则:

  • 区分大小写
  • 最大长度为64字节
  • 不能包含特殊字符,如空格、点号(.)、$、/、\和\0

集合命名规则:

  • 区分大小写
  • 最大长度为64字节
  • 可以包含点号(.),用于组织集合
  • 不能以"system."开头
  • 不能包含$和\0

Q14: 什么是命名空间?

A14: 命名空间是MongoDB中用于标识数据库和集合的唯一标识符,格式为database_name.collection_name。命名空间的最大长度为123字节。

Q15: 如何查看当前数据库中的所有集合?

A15: 可以使用以下命令查看当前数据库中的所有集合:

javascript
show collections

javascript
db.getCollectionNames()

Q16: 如何查看集合的索引信息?

A16: 可以使用db.collection_name.getIndexes()命令查看集合的索引信息:

javascript
db.mycollection.getIndexes()

Q17: 如何修改集合的验证规则?

A17: 可以使用db.runCommand()命令的collMod操作修改集合的验证规则:

javascript
db.runCommand({
  collMod: "mycollection",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email", "phone"],
      properties: {
        name: { bsonType: "string" },
        email: { bsonType: "string" },
        phone: { bsonType: "string" }
      }
    }
  }
});

Q18: 固定集合可以删除单个文档吗?

A18: 不可以,固定集合不支持删除单个文档,只能删除整个集合。如果需要删除固定集合中的数据,可以删除整个集合并重新创建。

Q19: 如何检查集合是否为固定集合?

A19: 可以使用db.collection_name.isCapped()命令检查集合是否为固定集合:

javascript
db.mycollection.isCapped()

Q20: 时间序列集合支持哪些查询操作?

A20: 时间序列集合支持所有标准的MongoDB查询操作,包括:

  • 时间范围查询
  • 聚合操作(如$match, $group, $sort等)
  • 索引查询
  • 全文搜索

此外,时间序列集合还支持专门的时间序列聚合操作,如$dateTrunc$setWindowFields等,用于高效的时间序列数据分析。