数据库是MongoDB中最高级别的数据组织单位。本课将深入讲解数据库的创建、管理、监控和删除等操作。
在深入了解具体操作之前,先理解MongoDB数据库的存储机制:
.ns文件中.0、.1等编号文件中MongoDB提供了多种方式来查看和管理数据库。
// 显示所有非空数据库
show dbs
// 显示当前使用的数据库
db
// 查看数据库详细统计信息
db.stats()
// 获取数据库对象(用于编程)
db.getName()
新创建的空数据库不会出现在 show dbs 列表中,这个设计有重要原因:
只有当数据库中至少有一个集合包含数据时,数据库才会在show dbs中显示。
// 查看详细的数据库统计
db.stats(1024) // 以KB为单位显示
统计字段说明:
db - 数据库名称collections - 集合数量objects - 文档总数avgObjSize - 平均文档大小(字节)dataSize - 数据总大小storageSize - 分配的存储空间indexes - 索引数量indexSize - 索引总大小MongoDB中的数据库创建和切换机制与传统数据库有所不同,体现了其"按需创建"的设计理念。
// 切换到指定数据库(如果不存在则标记为待创建)
use mydb
// 验证当前数据库
db
// 输出:mydb
// 此时数据库并未真正创建,只是设置了上下文
show dbs // mydb不会出现在列表中
// 插入数据后数据库才会真正创建
db.users.insertOne({name: "测试用户"})
// 现在数据库已创建,会出现在列表中
show dbs // mydb出现在列表中
MongoDB采用"惰性创建"机制,这种设计有重要优势:
当执行use database_name时,MongoDB只是在内存中设置了当前数据库上下文,真正的数据库创建发生在第一次插入数据时。
// 切换到已存在的数据库
use existing_db
// 切换到不存在的数据库(标记为待创建)
use new_database
// 切换回默认的test数据库
use test
// 在编程中动态切换数据库
var dbName = "dynamic_db";
var db = db.getSiblingDB(dbName);
ecommerce、blog、analyticsapp_dev、app_prod、app_test在实际项目中,合理使用多个数据库可以带来以下好处:
数据库删除是MongoDB中风险最高的操作之一,需要谨慎处理。本节将详细讲解删除操作的原理和安全措施。
// 1. 首先切换到要删除的数据库
use mydb
// 2. 确认当前数据库(重要:避免误删)
db.getName()
// 3. 查看数据库内容(确认要删除的数据)
show collections
db.stats()
// 4. 执行删除操作
db.dropDatabase()
// 5. 验证删除结果
show dbs // mydb应该不再出现在列表中
// 6. 尝试切换到已删除的数据库
use mydb // 可以切换,但数据库为空
db.stats() // 显示空数据库的统计信息
dropDatabase() 会永久删除数据库及其所有集合和数据,操作不可逆!删除前务必:
mongodump进行数据备份当执行dropDatabase()时,MongoDB会:
// 安全删除的完整流程示例
// 1. 备份数据
mongodump --db mydb --out /backup/mydb_$(date +%Y%m%d)
// 2. 验证备份
mongorestore --db mydb_test --dir /backup/mydb_20240101
// 3. 通知相关方
// 发送邮件或消息通知团队
// 4. 执行删除(在维护窗口期)
use mydb
db.dropDatabase()
// 5. 验证删除
show dbs
// 6. 记录操作日志
// 记录删除时间、操作人员、原因等信息
dropDatabase权限合理的数据库命名不仅便于管理,还能避免潜在的技术问题。MongoDB对数据库命名有明确的限制和推荐规范。
user_managementapp_dev、app_prod| 推荐命名 | 不推荐命名 | 原因 |
|---|---|---|
ecommerce |
ECommerce |
大小写不一致 |
user_management |
user management |
包含空格 |
blog_dev |
blog.dev |
包含点号 |
analytics_data |
analytics$data |
包含美元符号 |
这些命名限制主要基于以下技术考虑:
MongoDB包含三个特殊的系统数据库,它们对数据库的正常运行至关重要。理解这些系统数据库的作用对于MongoDB管理非常重要。
| 数据库 | 主要功能 | 存储内容 | 管理注意事项 |
|---|---|---|---|
| admin | 系统管理数据库 | 用户认证、角色权限、系统配置 | 不要删除,包含关键系统信息 |
| local | 本地运行数据库 | 副本集配置、oplog、本地数据 | 不会被复制到其他节点 |
| config | 分片配置数据库 | 分片信息、块分布、元数据 | 仅在分片集群中存在 |
// 切换到admin数据库
use admin
// 查看admin数据库的集合
show collections
// 查看系统用户
db.system.users.find()
// 查看角色权限
db.system.roles.find()
admin数据库的关键作用:
// 查看local数据库(仅限当前节点)
use local
show collections
// 查看操作日志(oplog)
db.oplog.rs.find().limit(5)
local数据库的特点:
// 在分片集群中查看config数据库
use config
show collections
// 查看分片信息
db.shards.find()
// 查看块分布信息
db.chunks.find().limit(5)
config数据库的作用:
系统数据库对MongoDB的正常运行至关重要,管理时需要注意:
数据库统计信息是监控数据库健康状况、进行容量规划和性能优化的关键工具。MongoDB提供了丰富的统计信息来帮助管理员了解数据库的运行状态。
// 查看数据库基本统计信息
db.stats()
// 以KB为单位显示统计信息
db.stats(1024)
// 以MB为单位显示统计信息
db.stats(1024 * 1024)
// 典型统计信息输出示例
{
"db" : "mydb", // 数据库名称
"collections" : 5, // 集合数量
"views" : 0, // 视图数量
"objects" : 1250, // 文档总数
"avgObjSize" : 512, // 平均文档大小(字节)
"dataSize" : 640000, // 数据总大小(字节)
"storageSize" : 294912, // 分配的存储空间(字节)
"numExtents" : 0, // 扩展数量(已弃用)
"indexes" : 3, // 索引数量
"indexSize" : 98304, // 索引总大小(字节)
"scaleFactor" : 1, // 缩放因子
"fsUsedSize" : 123456789, // 文件系统已使用空间
"fsTotalSize" : 987654321, // 文件系统总空间
"ok" : 1 // 命令执行状态
}
| 指标 | 含义 | 监控要点 | 优化建议 |
|---|---|---|---|
dataSize |
实际数据大小 | 数据增长趋势 | 定期归档旧数据 |
storageSize |
分配的存储空间 | 空间利用率 | 压缩或碎片整理 |
indexSize |
索引占用空间 | 索引与数据比例 | 优化索引策略 |
avgObjSize |
平均文档大小 | 文档设计合理性 | 优化文档结构 |
// 定期监控数据库增长
var stats = db.stats(1024); // KB单位
print("数据库大小: " + stats.dataSize + " KB");
print("存储分配: " + stats.storageSize + " KB");
print("索引大小: " + stats.indexSize + " KB");
// 计算空间利用率
var utilization = (stats.dataSize / stats.storageSize * 100).toFixed(2);
print("空间利用率: " + utilization + "%");
// 计算索引与数据比例
var indexRatio = (stats.indexSize / stats.dataSize * 100).toFixed(2);
print("索引数据比: " + indexRatio + "%");
数据库统计信息在实际运维中有多种重要用途:
了解如何查看和管理数据库中的集合是MongoDB操作的基础。MongoDB提供了多种方式来查看集合信息。
// 显示当前数据库的所有集合(简单列表)
show collections
// 获取集合名称数组(编程友好)
db.getCollectionNames()
// 查看集合的详细信息(包括系统集合)
db.getCollectionInfos()
// 查看特定类型的集合
db.getCollectionInfos({type: "collection"}) // 只显示普通集合
db.getCollectionInfos({type: "view"}) // 只显示视图
// 查看集合详细信息示例
db.getCollectionInfos()
// 输出示例
[
{
"name": "users",
"type": "collection",
"options": {},
"info": {
"readOnly": false,
"uuid": UUID("12345678-1234-5678-1234-567812345678")
},
"idIndex": {
"v": 2,
"key": {"_id": 1},
"name": "_id_",
"ns": "mydb.users"
}
},
{
"name": "products",
"type": "collection",
"options": {
"capped": true,
"size": 10485760
},
"info": {
"readOnly": false,
"uuid": UUID("87654321-4321-8765-4321-876543210987")
},
"idIndex": {
"v": 2,
"key": {"_id": 1},
"name": "_id_",
"ns": "mydb.products"
}
}
]
| 字段 | 说明 | 示例值 |
|---|---|---|
name |
集合名称 | "users" |
type |
集合类型 | "collection"或"view" |
options |
集合选项 | 上限集合大小、验证规则等 |
info.uuid |
集合唯一标识 | UUID格式的全局唯一标识 |
idIndex |
_id索引信息 | 默认_id索引的配置 |
// 1. 过滤系统集合(通常以system.开头)
var collections = db.getCollectionNames().filter(function(name) {
return !name.startsWith("system.");
});
print("用户集合: " + collections);
// 2. 统计集合数量
var collectionCount = db.getCollectionNames().length;
print("集合总数: " + collectionCount);
// 3. 检查特定集合是否存在
if (db.getCollectionNames().includes("users")) {
print("users集合存在");
} else {
print("users集合不存在");
}
// 4. 批量查看集合统计信息
db.getCollectionNames().forEach(function(collectionName) {
var stats = db[collectionName].stats();
print(collectionName + ": " + stats.count + " 个文档");
});
有效的集合管理可以提高数据库的可维护性和性能:
通过一个完整的电商数据库管理案例,综合运用本课学到的所有数据库操作知识。
我们要为一个电商平台创建数据库系统,包含用户管理、商品管理、订单管理等核心功能。
// 创建并切换到电商数据库
use ecommerce
// 验证当前数据库
db.getName()
// 输出:ecommerce
// 此时数据库为空,不会出现在show dbs中
show dbs // ecommerce不会显示
// 创建用户集合并插入示例数据
db.users.insertOne({
username: "alice",
email: "alice@example.com",
password: "encrypted_password",
role: "customer",
profile: {
firstName: "Alice",
lastName: "Smith",
phone: "+1234567890"
},
addresses: [
{
type: "home",
street: "123 Main St",
city: "New York",
zipCode: "10001"
}
],
created: new Date(),
lastLogin: new Date(),
status: "active"
})
// 批量插入更多用户数据
db.users.insertMany([
{
username: "bob",
email: "bob@example.com",
role: "admin",
created: new Date()
},
{
username: "charlie",
email: "charlie@example.com",
role: "vendor",
created: new Date()
}
])
// 创建商品集合并插入数据
db.products.insertOne({
name: "MacBook Pro 16英寸",
category: "electronics",
subcategory: "laptops",
brand: "Apple",
price: 2399.99,
currency: "USD",
stock: 25,
sku: "MBP16-2023",
attributes: {
processor: "M2 Pro",
memory: "16GB",
storage: "1TB SSD",
display: "16.2英寸 Liquid Retina XDR"
},
images: [
"image1.jpg",
"image2.jpg"
],
tags: ["apple", "macbook", "laptop", "pro"],
created: new Date(),
updated: new Date(),
status: "active"
})
// 插入更多商品
db.products.insertMany([
{
name: "iPhone 15 Pro",
category: "electronics",
price: 999.99,
stock: 100,
created: new Date()
},
{
name: "AirPods Pro",
category: "electronics",
price: 249.99,
stock: 50,
created: new Date()
}
])
// 创建订单集合
db.orders.insertOne({
orderNumber: "ORD-20240101-001",
customerId: ObjectId("507f1f77bcf86cd799439011"), // 引用用户ID
items: [
{
productId: ObjectId("507f1f77bcf86cd799439012"),
name: "MacBook Pro 16英寸",
quantity: 1,
price: 2399.99
},
{
productId: ObjectId("507f1f77bcf86cd799439013"),
name: "AirPods Pro",
quantity: 1,
price: 249.99
}
],
totalAmount: 2649.98,
currency: "USD",
shippingAddress: {
street: "123 Main St",
city: "New York",
zipCode: "10001"
},
status: "processing",
created: new Date(),
updated: new Date()
})
// 查看数据库统计信息(现在ecommerce会显示)
show dbs
// 查看数据库详细统计
db.stats(1024) // 以KB为单位
// 查看所有集合
show collections
// 查看集合详细信息
db.getCollectionInfos()
// 查看各集合文档数量
db.getCollectionNames().forEach(function(colName) {
var count = db[colName].countDocuments();
print(colName + "集合文档数量: " + count);
});
// 查看数据库大小,为备份做准备
var stats = db.stats(1024 * 1024); // MB单位
print("数据库大小: " + stats.dataSize + " MB");
print("需要备份的集合数量: " + stats.collections);
// 生成备份命令建议
print("建议备份命令:");
print("mongodump --db ecommerce --out /backup/ecommerce_$(date +%Y%m%d)");
通过这个完整的电商数据库案例,我们实践了:
通过以下练习题来巩固本课学到的数据库操作知识,模拟真实的企业数据库管理场景。
employees - 员工信息集合departments - 部门信息集合db.stats(1024)查看数据库大小(KB单位)db.getCollectionInfos()查看集合的详细信息完成本课学习后,你应该能够:
下一步学习建议:在掌握数据库操作的基础上,下一课将深入学习集合的详细操作,包括文档的增删改查等核心功能。