MongoDB数据库设计与性能优化
MongoDB概述
MongoDB是面向文档的NoSQL数据库,以JSON格式存储数据,支持灵活的Schema设计和强大的查询能力。
MongoDB vs 关系型数据库
| 概念 | MongoDB | MySQL |
|---|---|---|
| 数据库 | Database | Database |
| 表/集合 | Collection | Table |
| 行/文档 | Document | Row |
| 列/字段 | Field | Column |
| 主键 | _id | Primary Key |
| 索引 | Index | Index |
文档设计
嵌入式文档 vs 引用
// 嵌入式文档(一对一、一对少)
{
"_id": ObjectId("..."),
"name": "John Doe",
"email": "john@example.com",
"address": {
"street": "123 Main St",
"city": "New York",
"zip": "10001"
}
}
// 引用方式(一对多、多对多)
// users collection
{
"_id": ObjectId("user1"),
"name": "John Doe"
}
// orders collection
{
"_id": ObjectId("order1"),
"userId": ObjectId("user1"),
"products": [
{ "productId": ObjectId("prod1"), "quantity": 2 }
]
}
// 使用populate(Mongoose)
const user = await User.findById(userId).populate('orders');
Schema设计原则
- 频繁一起访问的数据嵌入
- 频繁更新的数据单独存储
- 超过16MB限制的数组使用引用
- 考虑读写比例设计
CRUD操作
// 插入文档
db.users.insertOne({
name: "Alice",
email: "alice@example.com",
age: 25,
tags: ["developer", "nodejs"]
});
db.users.insertMany([
{ name: "Bob", email: "bob@example.com" },
{ name: "Charlie", email: "charlie@example.com" }
]);
// 查询
db.users.findOne({ name: "Alice" });
db.users.find({
age: { $gte: 20, $lte: 30 },
tags: "nodejs"
});
// 投影
db.users.find({}, { name: 1, email: 1, _id: 0 });
// 排序、分页
db.users.find()
.sort({ age: -1 })
.skip(10)
.limit(10);
// 更新
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 26 }, $push: { tags: "python" } }
);
db.users.updateMany(
{ age: { $lt: 18 } },
{ $set: { status: "minor" } }
);
// 删除
db.users.deleteOne({ name: "Bob" });
db.users.deleteMany({ status: "inactive" });
聚合管道
// 基本聚合
db.orders.aggregate([
// 筛选
{ $match: { status: "completed" } },
// 展开
{ $unwind: "$products" },
// 分组统计
{
$group: {
_id: "$products.category",
totalSales: { $sum: "$products.price" },
count: { $sum: 1 },
avgPrice: { $avg: "$products.price" }
}
},
// 排序
{ $sort: { totalSales: -1 } },
// 限制结果
{ $limit: 10 },
// 重命名字段
{
$project: {
category: "$_id",
totalSales: 1,
count: 1,
_id: 0
}
}
]);
// Lookup关联查询
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userDetails"
}
},
{ $unwind: "$userDetails" }
]);
索引优化
// 创建索引
db.users.createIndex({ email: 1 }, { unique: true });
// 复合索引
db.orders.createIndex({ userId: 1, createdAt: -1 });
// 文本索引
db.articles.createIndex({ title: "text", content: "text" });
db.articles.find({ $text: { $search: "mongodb tutorial" } });
// 地理空间索引
db.places.createIndex({ location: "2dsphere" });
db.places.find({
location: {
$near: {
$geometry: { type: "Point", coordinates: [-73.97, 40.77] },
$maxDistance: 1000
}
}
});
// 查看索引
db.users.getIndexes();
// 分析查询性能
db.users.find({ email: "test@example.com" }).explain("executionStats");
// 索引策略
// ESR原则:Equality(等值) → Sort(排序) → Range(范围)
db.orders.createIndex({ status: 1, createdAt: -1, amount: 1 });
// 查询:status = "pending", sort by createdAt, filter by amount > 100
Python驱动
from pymongo import MongoClient, ASCENDING, DESCENDING
from bson import ObjectId
from datetime import datetime
# 连接
client = MongoClient('mongodb://localhost:27017/')
db = client['mydb']
# 插入
result = db.users.insert_one({
'name': 'Alice',
'email': 'alice@example.com',
'created_at': datetime.now()
})
print(f"Inserted ID: {result.inserted_id}")
# 批量插入
users = [{'name': f'User {i}'} for i in range(100)]
result = db.users.insert_many(users)
# 查询
user = db.users.find_one({'_id': ObjectId('...')})
for user in db.users.find({'age': {'$gte': 20}}).sort('name'):
print(user)
# 更新
result = db.users.update_one(
{'name': 'Alice'},
{'$set': {'age': 26}, '$currentDate': {'updated_at': True}}
)
# 聚合
pipeline = [
{'$match': {'status': 'active'}},
{'$group': {'_id': '$department', 'count': {'$sum': 1}}},
{'$sort': {'count': -1}}
]
for doc in db.users.aggregate(pipeline):
print(doc)
# 事务(副本集)
with client.start_session() as session:
with session.start_transaction():
db.accounts.update_one(
{'_id': ObjectId('...')},
{'$inc': {'balance': -100}},
session=session
)
db.accounts.update_one(
{'_id': ObjectId('...')},
{'$inc': {'balance': 100}},
session=session
)
性能优化
监控命令
// 服务器状态
db.serverStatus()
// 数据库统计
db.stats()
// 集合统计
db.users.stats()
// 慢查询日志
db.setProfilingLevel(1, 50) // 记录超过50ms的查询
db.system.profile.find().sort({ts: -1}).limit(10)
优化建议
- 合理设计Schema:根据访问模式嵌入或引用
- 创建合适索引:覆盖查询,避免全表扫描
- 限制返回字段:使用投影减少网络传输
- 批量操作:使用insertMany/updateMany
- 读写分离:副本集读取从节点
MongoDB是现代应用的强大数据存储选择,合理的设计和优化能够支撑大规模应用。
本文链接:https://www.kkkliao.cn/?id=755 转载需授权!
版权声明:本文由廖万里的博客发布,如需转载请注明出处。



手机流量卡
免费领卡
号卡合伙人
产品服务
关于本站
