7.9 KiB
7.9 KiB
存储与数据库重构方案(规划)
状态:第一阶段部分已落地(任务元数据落 SQLite、任务清理审计、素材 sha256)。 目的:后端当前仍以“内存 + 文件 + 任务级 SQLite + meta.json”为主要存储方式。本文档规划后续迁移到 PostgreSQL 元数据库,并优化任务生命周期和贴纸持久化。
1. 当前现状
| 数据 | 当前存储 | 问题 |
|---|---|---|
| 任务状态 / 事件 | JobManager._jobs 仅存内存 |
重启服务后任务记录丢失 |
| 任务输入 / 输出 | backend/service_workspace/{job_id} |
提交任务即建目录,未完成或被放弃的任务会遗留文件 |
| 词云坐标结果 | 每个任务生成一个 word_locations.db(SQLite) |
每个任务自带一份 SQLite 文件,查询分散 |
| 贴纸素材 | backend/service_assets/asset_xxx/asset.svg + meta.json |
素材元数据不是数据库,tint 等前端信息还依赖 localStorage |
| 设计模板 / 工程 | service_design_templates / service_projects 目录 + JSON |
模板和工程之间缺少数据库关联 |
| 画布文档 | 前端 localStorage | 无法跨设备,也无法作为后端权威数据 |
注意:当前不能认为系统已经在使用 PostgreSQL。代码中出现的 *.db 是词云算法自己写的 SQLite 结果文件,例如 backend/core/pipeline.py 的 word_locations 表。
2. 目标架构
整体原则:
- 文件继续存文件系统或对象存储(SVG / PNG / 遮罩 / Excel / 字体)。
- 业务元数据和引用关系存 PostgreSQL。
- 数据库保存路径引用,不保存大文件内容。
目标模型:
| 表 | 用途 | 说明 |
|---|---|---|
jobs |
任务主表 | job_id、状态、参数 JSONB、产物引用、创建时间 |
job_events |
任务进度事件 | SSE 进度事件落库,服务重启后可恢复 |
assets |
贴纸 / 素材表 | 素材元数据、文件路径、来源 job、sha256、tint |
design_documents |
画布文档 | CanvasDocument JSONB,绑定模板/工程 |
design_templates |
模板 | 模板元数据 + 画布文档引用 |
projects |
工程 | 模板 + 画布文档 + 素材引用 |
jobs 表字段建议
id uuid pk
status text -- submitted/running/success/failed/cancelled
stage text
progress int
message text
params jsonb -- 用户提交的词云参数
input_files jsonb -- mask/excel/font 引用
artifacts jsonb -- png/svg/svg_stroke/db/metrics 路径或文件 id
error text
created_at timestamptz
updated_at timestamptz
retention_until timestamptz -- 清理时间
assets 表字段建议
id uuid pk
name text
type text -- wordcloud / upload / shape / reference
mime_type text
storage_key text -- 文件系统路径或对象存储 key
width int
height int
file_size bigint
sha256 text -- 用于导入去重
source_job_id uuid nullable
tint text nullable
created_at timestamptz
deleted_at timestamptz nullable
3. 任务存储链路
现状是 POST /api/jobs 提交时直接创建 job 目录和保存上传文件。
目标改动:
POST /api/jobs只写jobs表,状态为submitted或queued。- 上传文件先落到临时上传区,或延迟到进入 runner 前再落盘。
- runner 真正开始时才创建任务的
input/和output/目录。 - 任务完成后把产物路径/文件 id 写入
jobs.artifacts。 - 增加后台清理任务:
- 清理
completed且未被贴纸/工程引用的任务文件。 - 支持按
retention_until保留最近结果。 - 被用户导入为贴纸的任务文件可延长保留时间。
- 清理
这样不会每次申请都攒下一堆用不上的目录和文件。
4. 贴纸持久化
贴纸在当前 frontend/src/lib/stickerLibrary.ts 中已经走后端 POST /api/assets,但元数据仍写在 meta.json,tint 还保存在 localStorage。
目标改动:
assets表作为贴纸唯一权威来源。POST /api/assets:写文件系统 + 写assets表,返回asset_id。GET /api/assets:从数据库读取列表。PATCH /api/assets/{id}:更新 tint、name 等元数据。DELETE /api/assets/{id}:物理删除文件 + 记录,或软删除防止破坏设计文档引用。POST /api/assets/from-job/{job_id}:沿用同一逻辑,写入source_job_id。- 前端不再依赖 localStorage 保存贴纸 tint,加载和更新都走 API。
5. 画布文档与模板
当前画布保存在 localStorage,模板保存成目录 JSON。
目标改动:
design_documents保存CanvasDocumentJSONB。- 画布每次保存调用
PUT /api/documents/{id}。 design_templates引用design_documents,同时记录reference_asset_ids和封面图。- 后续实现画布导出导入时,导入包可直接写入
design_documents,并把包内素材批量写入assets表。
6. PostgreSQL 接入方式
建议:
- 引入 SQLAlchemy(或 asyncpg)作为数据库访问层。
- 使用 Alembic 管理 migration。
- 在
docker-compose.yml增加 PostgreSQL 服务。 - 通过环境变量注入
DATABASE_URL,本地开发和 Docker 使用不同配置。 - 暂不把词云算法的
word_locations表强制迁移到 PostgreSQL,可以保留 SQLite 作为任务内部产物,再通过导出接口把需要的布局结果写入jobs或独立布局表中。
7. 分阶段实施
阶段一:接入 PostgreSQL,先做贴纸和任务元数据(任务元数据已用 SQLite 先行落地)
- 建
assets/jobs/job_events表。 assets接口从文件 meta 迁移到 DB。- 提交任务仍可使用现有 runner,但把任务状态写入 DB。
- 不改动词云算法核心。
阶段二:任务生命周期优化(清理审计已落地)
POST /api/jobs只记账,不提前建目录。- runner 开始前再落 input/output。
- 增加 TTL 清理任务。
- 任务列表、任务详情改为从 DB 查询。
阶段三:画布文档和导入包
- 建
design_documents/design_templates/projects表。 - 画布保存从 localStorage 改为后端文档接口。
wcd导入导出包直接对接这些表。
8. 风险与注意点
- 现有任务接口依赖内存中的
JobManager,迁到 DB 后需要兼容 SSE 进度事件。 - 文件迁移只能做增量:老素材目录可先保留,新写入走 DB。
- 删除素材要检查
design_documents引用,避免出现缺失贴纸。 - tint 从前端 localStorage 迁移到 DB 时,需要兼容旧浏览器状态。
10. 已落地实现
backend/service/metadata_store.py:SQLite 元数据jobs/job_events。backend/service/job_manager.py:任务状态和事件落库,服务重启可恢复。backend/service/storage.py:任务目录占用、过期审计、可清理能力。backend/service/storage_metrics.py:dry-run 指标和显式--apply清理。backend/service/app.py:GET /api/maintenance/storage-summary。docs/DATA_STORAGE_OPTIMIZATION.md:完整空间/效能指标。
注:当前项目没有接入 PostgreSQL。代码里的
*.db是词云算法自己的 SQLite 结果文件;新加的service_metadata/app.db是业务元数据先行层。jobs/job_events表结构设计上可平滑迁移到 PostgreSQL。
9. 相关文件参考
backend/service/app.py:目前的任务、素材、模板 API。backend/service/job_manager.py:内存中的任务状态。backend/service/storage.py:任务目录创建。backend/service/runner.py:任务运行与产物扫描。backend/core/pipeline.py:词云结果 SQLite 写入。frontend/src/lib/stickerLibrary.ts:前端贴纸库。docker-compose.yml:服务编排,后续加 PostgreSQL。