外观
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.0 | MongoDB 5.0 |
|---|---|---|
| 时间序列集合 | 不支持 | 支持 |
| 文档验证 | 基本支持 | 增强的验证规则 |
| 集合统计信息 | 基本统计 | 改进的统计信息,包括更详细的索引数据 |
| 分片集合支持 | 支持 | 增强的分片集合支持,提高分片性能 |
| 事务支持 | 支持 | 增强的事务支持,提高事务性能 |
MongoDB 5.0 与 6.0 的差异
| 功能 | MongoDB 5.0 | MongoDB 6.0 |
|---|---|---|
| 向量搜索 | 不支持 | 支持 |
| 文档存储格式 | 传统格式 | 改进的存储格式,提高查询性能 |
| 集合级加密 | 基本支持 | 增强的集合级加密,支持更多加密算法 |
| 时间序列集合 | 支持 | 增强的时间序列集合,支持更灵活的架构 |
| 事务支持 | 支持 | 增强的事务支持,提高事务性能 |
生产实践建议
数据库设计建议
- 根据业务需求设计数据库结构:避免过度设计,根据实际业务需求设计数据库结构
- 合理规划数据库数量:避免创建过多的数据库,每个数据库都有自己的开销
- 使用有意义的名称:数据库和集合名称应该反映其用途,便于理解和维护
- 考虑数据增长:设计时考虑数据的增长趋势,为未来的扩展做好准备
集合设计建议
- 根据访问模式设计集合结构:根据查询和写入模式设计集合结构,优化性能
- 避免单个集合过大:对于大型集合,考虑分片或拆分集合
- 合理使用嵌入文档:根据访问模式决定是嵌入文档还是使用引用
- 为集合设置适当的验证规则:使用文档验证确保数据质量
固定集合最佳实践
- 用于日志和事件数据:固定集合适合存储日志、事件等时序数据
- 合理设置大小:根据数据量和保留时间设置合适的大小
- 考虑查询模式:固定集合查询时无需排序,适合按插入顺序查询
- 避免频繁更新:固定集合不适合频繁更新的场景
时间序列集合最佳实践
- 用于时间序列数据:时间序列集合适合存储传感器数据、监控指标等时间序列数据
- 合理设置粒度:根据数据的时间间隔设置合适的粒度
- 使用元数据字段:合理使用元数据字段,提高查询性能
- 设置数据过期时间:根据业务需求设置数据自动过期时间
常见问题(FAQ)
Q1: 如何创建数据库?
A1: 在MongoDB中,创建数据库的方法是使用use命令切换到指定数据库,然后向该数据库中插入数据。当首次向数据库中插入数据时,MongoDB会自动创建该数据库。
javascript
use mydb // 切换到mydb数据库,如果不存在则创建
db.mycollection.insertOne({ name: "test" }) // 插入数据,触发数据库创建Q2: 如何创建集合?
A2: 创建集合的方法有两种:
- 显式创建:使用
db.createCollection()命令显式创建集合 - 隐式创建:直接向集合中插入数据,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等,用于高效的时间序列数据分析。
