Day 9: 数据库操作
数据库设计、查询优化、性能调优,让数据操作又快又稳。
数据库设计
表结构设计
你:设计电商系统的数据库表,包含用户、商品、订单、购物车
Claude 会设计:
- 用户表(用户信息、权限)
- 商品表(基本信息、库存、价格)
- 订单表(订单状态、金额、地址)
- 订单详情表(商品、数量、单价)
- 购物车表(用户、商品、数量)
关系设计
你:设计博客系统的表关系,用户、文章、评论、标签
关系类型:
- 一对多:用户 → 文章
- 多对多:文章 ↔ 标签
- 一对多:文章 → 评论
索引设计
你:为用户表添加合适的索引,优化查询性能
MongoDB 操作
文档设计
你:用 MongoDB 设计博客系统的文档结构
// 用户文档
{
_id: ObjectId,
username: "john_doe",
email: "john@example.com",
profile: {
avatar: "avatar.jpg",
bio: "前端开发者"
},
createdAt: Date
}
// 文章文档
{
_id: ObjectId,
title: "React 最佳实践",
content: "文章内容...",
author: ObjectId, // 引用用户ID
tags: ["react", "javascript"],
comments: [ // 嵌套评论
{
_id: ObjectId,
user: ObjectId,
content: "很好的文章",
createdAt: Date
}
]
}
Mongoose 模型
你:用 Mongoose 创建用户和文章模型,包含验证规则
复杂查询
你:查询最近30天发布的文章,按点赞数排序,支持分页
const articles = await Article.find({
createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }
})
.populate('author', 'username avatar')
.sort({ likes: -1 })
.skip((page - 1) * limit)
.limit(limit);
MySQL/PostgreSQL 操作
Prisma ORM
你:用 Prisma 设计用户订单系统的数据模型
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
orders Order[]
createdAt DateTime @default(now())
}
model Order {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id])
total Decimal
status String
items OrderItem[]
createdAt DateTime @default(now())
}
复杂查询
你:查询用户的订单统计信息,包含总金额、订单数量、最近订单时间
事务处理
你:实现下单功能,减库存和创建订单要在同一个事务中
查询优化
慢查询分析
你:分析这个查询为什么慢,怎么优化
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at > '2023-01-01'
GROUP BY u.id;
索引优化
你:为这个查询添加合适的索引
分页优化
你:优化大数据量的分页查询,避免 OFFSET 性能问题
使用游标分页:
-- 第一页
SELECT * FROM articles WHERE id > 0 ORDER BY id LIMIT 20;
-- 下一页(假设上一页最后一条记录 id 为 20)
SELECT * FROM articles WHERE id > 20 ORDER BY id LIMIT 20;
缓存策略
Redis 缓存
你:为商品信息添加 Redis 缓存,设置合适的过期时间
查询缓存
你:实现查询结果缓存,相同查询直接返回缓存数据
缓存更新
你:商品信息更新时,同步更新 Redis 缓存
数据迁移
数据库迁移
你:创建数据库迁移脚本,给用户表添加手机号字段
数据导入导出
你:从 CSV 文件批量导入用户数据到数据库
数据同步
你:实现 MySQL 到 MongoDB 的数据同步脚本
常用查询场景
统计查询
你:查询每月的订单统计,包含订单数和总金额
SELECT
DATE_FORMAT(created_at, '%Y-%m') as month,
COUNT(*) as order_count,
SUM(total) as total_amount
FROM orders
WHERE created_at >= '2023-01-01'
GROUP BY month
ORDER BY month;
排行查询
你:查询销量前10的商品,显示商品信息和销量
关联查询
你:查询用户最近的5个订单,包含订单商品详情
搜索功能
你:实现商品的全文搜索,支持按名称、描述、标签搜索
性能监控
查询监控
你:监控数据库慢查询,记录执行时间超过1秒的查询
连接池管理
你:配置数据库连接池,优化连接使用效率
数据库备份
你:设置自动备份策略,每天凌晨备份数据库
NoSQL vs SQL 选择
何时用 MongoDB
- 数据结构灵活多变
- 需要水平扩展
- 文档型数据(如博客、CMS)
- 快速原型开发
何时用 MySQL/PostgreSQL
- 强一致性要求
- 复杂关系查询
- 事务处理重要
- 数据分析需求
数据库安全
SQL 注入防护
你:检查这个查询是否有 SQL 注入风险,如何修复
// 危险的查询
const query = `SELECT * FROM users WHERE id = ${userId}`;
// 安全的查询
const query = `SELECT * FROM users WHERE id = ?`;
db.query(query, [userId]);
权限控制
你:创建只读用户权限,只能查询特定表
数据加密
你:对用户敏感信息(手机号、身份证)进行加密存储
数据库维护
表优化
你:分析用户表的存储空间使用情况,清理冗余数据
分表分库
你:用户量太大了,设计用户表的分表策略
读写分离
你:配置主从数据库,读操作走从库,写操作走主库
数据库经验:设计时多想想未来的扩展,写查询时多考虑性能,备份比什么都重要。
第三阶段完成! 恭喜你掌握了进阶开发技能。最后一个阶段,学习测试、部署等高手技能。
下一步
Day 10: 测试驱动 - 编写测试保证代码质量
练习建议:
- 设计一个完整的数据库表结构
- 写几个复杂查询,体验一下优化前后的性能差异
- 试试用 Claude 分析慢查询的优化方案