Files
wordcloud/docs/DESIGN_DATA_STORAGE_PLAN.md
T

7.9 KiB
Raw Blame History

存储与数据库重构方案(规划)

状态:第一阶段部分已落地(任务元数据落 SQLite、任务清理审计、素材 sha256)。 目的:后端当前仍以“内存 + 文件 + 任务级 SQLite + meta.json”为主要存储方式。本文档规划后续迁移到 PostgreSQL 元数据库,并优化任务生命周期和贴纸持久化。

1. 当前现状

数据 当前存储 问题
任务状态 / 事件 JobManager._jobs 仅存内存 重启服务后任务记录丢失
任务输入 / 输出 backend/service_workspace/{job_id} 提交任务即建目录,未完成或被放弃的任务会遗留文件
词云坐标结果 每个任务生成一个 word_locations.dbSQLite 每个任务自带一份 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.pyword_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 目录和保存上传文件。

目标改动:

  1. POST /api/jobs 只写 jobs 表,状态为 submittedqueued
  2. 上传文件先落到临时上传区,或延迟到进入 runner 前再落盘。
  3. runner 真正开始时才创建任务的 input/output/ 目录。
  4. 任务完成后把产物路径/文件 id 写入 jobs.artifacts
  5. 增加后台清理任务:
    • 清理 completed 且未被贴纸/工程引用的任务文件。
    • 支持按 retention_until 保留最近结果。
    • 被用户导入为贴纸的任务文件可延长保留时间。

这样不会每次申请都攒下一堆用不上的目录和文件。

4. 贴纸持久化

贴纸在当前 frontend/src/lib/stickerLibrary.ts 中已经走后端 POST /api/assets,但元数据仍写在 meta.jsontint 还保存在 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 保存 CanvasDocument JSONB。
  • 画布每次保存调用 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.pySQLite 元数据 jobs / job_events
  • backend/service/job_manager.py:任务状态和事件落库,服务重启可恢复。
  • backend/service/storage.py:任务目录占用、过期审计、可清理能力。
  • backend/service/storage_metrics.pydry-run 指标和显式 --apply 清理。
  • backend/service/app.pyGET /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。