crm/docs/screenshot-storage-comparison.md

229 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 截图存储方案对比
## 方案对比总览
| 特性 | 文件系统存储 | 数据库 Base64 存储 ✅ |
| ---------------- | ------------------- | ------------------------- |
| **数据一致性** | ❌ 可能不一致 | ✅ 完全一致 |
| **备份恢复** | ❌ 需要分别备份 | ✅ 只需备份数据库 |
| **部署复杂度** | ❌ 需要配置文件服务 | ✅ 无需额外配置 |
| **多服务器部署** | ❌ 需要共享存储 | ✅ 无需共享存储 |
| **维护成本** | ❌ 需要清理孤立文件 | ✅ 自动管理 |
| **数据大小** | ✅ 原始大小 | ⚠️ 增加 33% |
| **查询性能** | ✅ 不影响 | ✅ 不影响LONGTEXT优化 |
## 架构对比
### 旧方案:文件系统存储
```
┌─────────────┐
│ 前端 │
└──────┬──────┘
│ 1. 上传图片
┌─────────────────┐
│ 后端 API │
│ - 保存到文件 │──────┐
│ - 返回路径 │ │ 2. 写入文件
└──────┬──────────┘ ▼
│ ┌──────────────┐
│ 3. 保存路径 │ 文件系统 │
▼ │ /uploads/... │
┌─────────────────┐ └──────────────┘
│ 数据库 │
│ screenshots: │
│ ["/static/..."] │
└─────────────────┘
问题:
❌ 数据库和文件系统可能不一致
❌ 删除记录时文件可能残留
❌ 文件被删除但数据库仍有记录
```
### 新方案:数据库 Base64 存储
```
┌─────────────┐
│ 前端 │
└──────┬──────┘
│ 1. 上传图片
┌─────────────────────┐
│ 后端 API │
│ - 转换为 Base64 │
│ - 返回 Data URL │
└──────┬──────────────┘
│ 2. 保存 Base64
┌─────────────────────┐
│ 数据库 │
│ screenshots: │
│ ["data:image/..."] │
└─────────────────────┘
优势:
✅ 数据完全一致
✅ 删除记录时图片自动删除
✅ 备份恢复只需处理数据库
```
## 数据流对比
### 上传流程
**旧方案**:
```
图片文件 → 保存到磁盘 → 生成路径 → 存入数据库
(可能失败) (返回前端) (可能失败)
```
**新方案**:
```
图片文件 → 转换 Base64 → 存入数据库
(一次性完成)
```
### 读取流程
**旧方案**:
```
查询数据库 → 获取路径 → 配置静态服务 → 前端请求文件
(可能不存在) (需要配置) (可能 404)
```
**新方案**:
```
查询数据库 → 获取 Base64 → 前端直接显示
(一定存在) (无需额外请求)
```
## 实际案例
### 问题场景(旧方案)
```
用户报告GET /static/uploads/screenshots/bd232714-58ac-472b-b3d0-18e7e768afe0.jpg 404
原因分析:
1. 数据库中有记录screenshots: ["/static/uploads/screenshots/bd232714..."]
2. 但文件系统中文件不存在
3. 可能原因:
- 手动清理了上传目录
- 服务器迁移时未同步文件
- 磁盘故障导致文件丢失
```
### 解决方案(新方案)
```
数据库记录:
{
"screenshots": [
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
]
}
特点:
✅ 图片数据直接在数据库中
✅ 查询到记录就一定能显示图片
✅ 不会出现 404 错误
```
## 性能影响分析
### 存储空间
```
原始图片: 1 MB
Base64 编码: 1.33 MB (+33%)
示例:
- 5 张截图,每张 500 KB
- 文件系统: 2.5 MB
- Base64: 3.3 MB (+0.8 MB)
```
### 数据库性能
```sql
-- LONGTEXT 字段不影响其他字段查询
SELECT id, customer_name, created_at
FROM customers;
-- ✅ 不会加载 screenshots 字段
-- 只有明确查询时才加载
SELECT screenshots
FROM customers
WHERE id = 'xxx';
-- ⚠️ 会加载完整的 Base64 数据
```
### 网络传输
**旧方案**:
```
1. API 请求: 返回路径 (~100 bytes)
2. 图片请求: 下载文件 (1 MB)
总计: 2 次请求
```
**新方案**:
```
1. API 请求: 返回 Base64 (1.33 MB)
总计: 1 次请求
```
## 最佳实践建议
### ✅ 适合使用 Base64 存储的场景
- 截图、缩略图等小图片
- 需要保证数据一致性
- 简化部署和维护
- 单张图片 < 2 MB
- 每条记录图片数量 < 10
### ⚠️ 不适合的场景
- 高清大图> 5 MB
- 大量图片(> 20 张/记录)
- 需要图片处理(缩放、裁剪)
- 需要 CDN 加速
### 💡 推荐方案
```
小图片(截图、头像): Base64 存储 ✅
大图片(产品图、相册): 对象存储OSS+ URL 引用
```
## 迁移检查清单
- [x] 数据库字段升级为 LONGTEXT
- [x] 上传接口返回 Base64 Data URL
- [x] 前端代码兼容两种格式
- [ ] 测试上传功能
- [ ] 测试显示功能
- [ ] 验证数据库存储
- [ ] 性能测试
- [ ] 备份验证
## 总结
通过将截图存储从文件系统迁移到数据库 Base64 存储,我们:
1. **彻底解决了数据一致性问题** - 这是最重要的改进
2. **简化了部署和维护** - 无需管理文件系统
3. **提高了系统可靠性** - 不会出现文件丢失的情况
4. **付出了可接受的代价** - 存储空间增加 33%,但换来了更好的数据完整性
这是一个典型的**用空间换可靠性**的工程决策。