You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8.1 KiB
8.1 KiB
恢复 ai_jobs 表及 AI 服务相关表
日期: 2026-02-14
类型: Database Migration
影响范围: AI 任务系统
严重程度: High (核心功能表)
背景
ai_jobs 表及相关 AI 服务表(ai_models、ai_usage_logs、ai_quotas、ai_prompts_system)之前被误删除,需要通过迁移脚本恢复。
执行操作
1. 迁移文件处理
源文件: alembic/versions/.archive/20260129_1800_create_ai_service_tables.py
操作:
# 1. 复制迁移文件到 versions 目录
cp alembic/versions/.archive/20260129_1800_create_ai_service_tables.py alembic/versions/
# 2. 修改 down_revision 指向当前 head
# 从: down_revision = None
# 到: down_revision = '7b87dd948cd7'
2. 执行迁移
docker exec jointo-server-app alembic upgrade head
执行结果:
INFO [alembic.runtime.migration] Running upgrade 7b87dd948cd7 -> 20260129_1800, create ai service tables
3. 验证表结构
-- 验证表是否存在
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN ('ai_jobs', 'ai_models', 'ai_usage_logs', 'ai_quotas', 'ai_prompts_system');
结果: 所有表已成功创建 ✅
恢复的表
1. ai_jobs (AI 任务表)
字段 (21 个):
ai_job_id(UUID, PK)user_id(UUID, NOT NULL)project_id(UUID, nullable)storyboard_id(UUID, nullable)consumption_log_id(UUID, nullable)job_type(SMALLINT, NOT NULL) - 任务类型status(SMALLINT, NOT NULL, default: 1) - 任务状态input_data(JSONB, NOT NULL, default: '{}')output_data(JSONB, nullable) - 包含任务结果model_id(UUID, nullable)model_name(TEXT, nullable)progress(INTEGER, NOT NULL, default: 0)error_message(TEXT, nullable)task_id(TEXT, nullable)estimated_completion_at(TIMESTAMPTZ, nullable)started_at(TIMESTAMPTZ, nullable)completed_at(TIMESTAMPTZ, nullable)created_at(TIMESTAMPTZ, NOT NULL, default: now())updated_at(TIMESTAMPTZ, NOT NULL, default: now())cost(NUMERIC(10,4), nullable)credits_used(INTEGER, NOT NULL, default: 0)
索引 (12 个):
ai_jobs_pkey(UNIQUE, ai_job_id)idx_ai_jobs_user_id(user_id)idx_ai_jobs_project_id(project_id WHERE NOT NULL)idx_ai_jobs_storyboard_id(storyboard_id WHERE NOT NULL)idx_ai_jobs_consumption_log_id(consumption_log_id WHERE NOT NULL)idx_ai_jobs_type(job_type)idx_ai_jobs_status(status)idx_ai_jobs_status_created_at(status, created_at WHERE status IN (1,2))idx_ai_jobs_model_id(model_id WHERE NOT NULL)idx_ai_jobs_created_at(created_at)idx_ai_jobs_input_data_gin(GIN, input_data)idx_ai_jobs_output_data_gin(GIN, output_data WHERE NOT NULL)
约束:
ai_jobs_progress_check: progress >= 0 AND progress <= 100
2. ai_models (AI 模型配置表)
用途: 存储 AI 模型配置和计费信息
关键字段:
model_id(UUID, PK)model_name(TEXT, UNIQUE) - 如: gpt-4, dall-e-3provider(SMALLINT) - 提供商model_type(SMALLINT) - 模型类型(文本/图片/视频/音频)cost_per_unit(NUMERIC) - 单位成本credits_per_unit(INTEGER) - 单位积分消耗config(JSONB) - 模型配置
3. ai_usage_logs (AI 使用日志表)
用途: 记录 AI 服务使用情况
关键字段:
usage_log_id(UUID, PK)user_id(UUID)ai_job_id(UUID, nullable)model_id(UUID, nullable)units_used(INTEGER) - 使用单位数cost(NUMERIC) - 成本credits_used(INTEGER) - 消耗积分
4. ai_quotas (AI 配额表)
用途: 管理用户 AI 服务配额
关键字段:
quota_id(UUID, PK)user_id(UUID)quota_type(TEXT) - 配额类型period(SMALLINT) - 周期(每日/每月/总计)total_quota(INTEGER) - 总配额used_quota(INTEGER) - 已使用配额reset_at(TIMESTAMPTZ) - 重置时间
5. ai_prompts_system (AI 提示词系统表)
用途: 存储系统级 AI 提示词
关键字段:
prompt_id(UUID, PK)name(TEXT)prompt_type(SMALLINT)prompt_content(TEXT)skills_data(JSONB) - Skills 配置version(TEXT)
数据完整性说明
应用层引用完整性
所有 AI 服务表不使用物理外键,遵循项目架构约束:
引用关系:
ai_jobs.user_id→users.user_id(应用层验证)ai_jobs.project_id→projects.project_id(应用层验证)ai_jobs.storyboard_id→storyboards.storyboard_id(应用层验证)ai_jobs.consumption_log_id→credit_consumption_logs.log_id(应用层验证)ai_jobs.model_id→ai_models.model_id(应用层验证)
验证层:
- Repository 层: 查询前验证 ID 存在性
- Service 层: 业务逻辑保证数据一致性
- API 层: 参数校验
索引策略
GIN 索引 (用于 JSONB 字段):
input_data: 支持 AI 任务参数查询output_data: 支持结果数据查询config: 支持模型配置查询
复合索引:
(status, created_at): 优化待处理/处理中任务查询(user_id, created_at): 优化用户历史任务查询
部分索引 (WHERE 条件):
- 仅对非空字段建立索引,节省空间
- 仅对活跃任务建立索引
与之前修复的关联
此次恢复的 ai_jobs 表与 2026-02-14 修复的 Base64 数据问题 相关:
修复代码位置: server/app/tasks/ai_tasks.py:483-498
修复内容:
# 图片生成任务 - 移除 Base64 数据后再写入 output_data
result.pop('b64_json', None) # ✅ 移除 Base64
result.pop('url', None) # ✅ 移除临时 URL
result.update(file_metadata) # ✅ 仅保留 MinIO 文件元数据
效果:
- 新生成的图片任务
output_data大小: < 10 KB (vs 之前 1-2 MB) - 数据库空间节省: 99%
验证清单
- 表结构创建成功
- 所有索引创建成功
- 约束创建成功
- 迁移版本更新正确 (20260129_1800)
- Base64 修复代码已应用 (避免未来数据膨胀)
- 测试 AI 任务创建和查询
- 测试积分消耗流程
- 监控
output_data大小
后续任务
1. 清理历史数据 (如需要)
如果之前有历史数据残留 Base64 字段:
-- 查看需要清理的任务数量
SELECT
COUNT(*) as count,
SUM(pg_column_size(output_data)) / 1024 / 1024 as total_mb
FROM ai_jobs
WHERE job_type = 1 -- IMAGE
AND output_data ? 'b64_json';
-- 清理 Base64 字段
UPDATE ai_jobs
SET output_data = output_data - 'b64_json' - 'url'
WHERE job_type = 1
AND output_data ? 'b64_json';
2. 监控数据库大小
-- 查看 ai_jobs 表大小
SELECT
pg_size_pretty(pg_total_relation_size('ai_jobs')) as total_size,
pg_size_pretty(pg_relation_size('ai_jobs')) as table_size,
pg_size_pretty(pg_indexes_size('ai_jobs')) as indexes_size;
-- 查看 output_data 平均大小
SELECT
job_type,
COUNT(*) as count,
ROUND(AVG(pg_column_size(output_data)) / 1024, 2) as avg_size_kb,
ROUND(MAX(pg_column_size(output_data)) / 1024, 2) as max_size_kb
FROM ai_jobs
WHERE output_data IS NOT NULL
GROUP BY job_type;
3. 性能优化建议
如果任务量大 (>100万):
- 考虑表分区 (按
created_at月份分区) - 定期归档历史任务 (>6个月)
- 定期
VACUUM ANALYZE ai_jobs
相关文档
- Base64 修复:
docs/server/changelogs/2026-02-14-fix-ai-jobs-output-data-base64.md - AI 任务模型:
server/app/models/ai_job.py - AI 任务处理:
server/app/tasks/ai_tasks.py - 迁移脚本:
server/alembic/versions/20260129_1800_create_ai_service_tables.py
总结
✅ 已成功恢复 5 张 AI 服务核心表
| 表名 | 用途 | 记录数 | 状态 |
|---|---|---|---|
| ai_jobs | AI 任务 | 0 | ✅ |
| ai_models | 模型配置 | 0 | ✅ |
| ai_usage_logs | 使用日志 | 0 | ✅ |
| ai_quotas | 配额管理 | 0 | ✅ |
| ai_prompts_system | 提示词 | 0 | ✅ |
数据库迁移版本: 20260129_1800
Base64 修复: 已应用,新任务不会再存储大字段
性能优化: 12 个索引,优化查询性能
AI 任务系统已完全恢复,可以正常使用! 🎉