# 数据库设计方案 (最终版)
本文档定义了项目重构后的核心数据库结构,旨在实现对机器学习模型和预测历史的统一、高效管理。该设计方案结合了业务需求、前端UI逻辑、后端代码实现以及现有数据库结构,并经过了多次迭代确认。
## 设计原则
- **模型集中化**: 所有模型的元数据统一存储,摆脱对文件系统的依赖。
- **数据一致性**: 通过逻辑外键确保预测记录与模型版本精确关联。
- **查询高性能**: 通过冗余关键字段,避免在查询列表时进行不必要的`JOIN`操作。
- **可扩展性**: 使用JSON字段存储灵活、复杂的范围定义和文件路径,适应未来业务变化。
- **结构清晰**: 物理文件(模型、日志、预测结果)与数据库记录分离,数据库只存元数据和路径,保持自身轻量。
---
## 预测结果JSON保存到:saved_predictions
## 表结构定义
### 表1:`models`
这张表是模型管理的核心,负责存储所有模型版本的全生命周期信息。
| 字段名 | 类型 | 确认理由与说明 |
| :--- | :--- | :--- |
| `id` | INTEGER | 主键,系统内部使用。 |
| `model_uid` | TEXT | **[关键]** 用户可见的唯一ID,由后端生成,用于API调用和逻辑关联。 |
| `display_name` | TEXT | **[建议新增]** 用户可自定义的别名,如“夏季促销模型”,提升易用性。 |
| `model_type` | TEXT | **已确认.** 核心参数,如 `mlstm`, `kan`。 |
| `training_mode` | TEXT | **已确认.** 模型的训练范围: `product`, `store`, `global`。 |
| `training_scope` | TEXT (JSON) | **[最终版]** **精确描述训练范围,并包含中文名。**
- **按药品训练**: `{"product": {"id": "P001", "name": "阿莫西林"}, "stores": "all"}` 或 `{"product": {"id": "P001", "name": "阿莫西林"}, "stores": [{"id": "S001", "name": "城西店"}]}`
- **按店铺训练**: `{"store": {"id": "S001", "name": "城西店"}, "products": "all"}` 或 `{"store": {"id": "S001", "name": "城西店"}, "products": [{"id": "P001", "name": "阿莫西林"}, {"id": "P002", "name": "布洛芬"}]}`
- **全局训练**: `{"stores": "all", "products": "all"}` 或 `{"stores": [{"id": "S001", "name": "城西店"}], "products": [{"id": "P001", "name": "阿莫西林"}]}` |
| `parent_model_id` | INTEGER | **已确认.** 外键,指向自身 `id`,用于实现“继续训练”功能,形成版本链。 |
| `version` | TEXT | **已确认.** 模型版本号,如 `v1`, `v2`。 |
| `status` | TEXT | **已确认.** 模型状态,如 `active`, `archived`,用于控制模型是否可用。 |
| `training_params` | TEXT (JSON) | **已确认.** 存储训练时的超参数,如 `{"epochs": 50, "aggregation_method": "sum"}`。 |
| `performance_metrics` | TEXT (JSON) | **已确认.** 存储性能指标,如 `{"R2": 0.85, "RMSE": ...}`。 |
| `artifacts` | TEXT (JSON) | **[采纳建议]** **存储与模型相关的所有文件路径。** 所有文件均采用**扁平化结构**存放在 `saved_models/` 目录下。示例:
`{"best_model": "saved_models/product_P001_mlstm_best.pth", "versioned_model": "saved_models/product_P001_mlstm_v1.pth", "loss_curve_plot": "saved_models/product_P001_mlstm_v1_loss.png", "loss_curve_data": "saved_models/product_P001_mlstm_v1_history.json"}` |
| `created_at` | DATETIME | **已确认.** 模型的创建时间。 |
---
### 表2:`prediction_history`
这张表用于记录每一次预测任务的结果,其结构在现有基础上进行了优化,以实现高效查询和完整追溯。
| 字段名 | 类型 | 确认理由与说明 |
| :--- | :--- | :--- |
| `id` | INTEGER | **已确认.** 主键,自增。 |
| `prediction_uid` | TEXT | **已确认.** 唯一的预测ID (UUID),用于API调用。 |
| `model_id` | TEXT | **[核心变更]** **使用的模型的唯一标识符。** 在重构后,此字段的值应该与 `models` 表中的某条记录的 `model_uid` 相对应,从而建立起逻辑关联。 |
| `model_type` | TEXT | **已确认 (冗余).** 冗余存储模型类型(如 `mlstm`),用于在不关联查询的情况下快速筛选历史记录。 |
| `product_name` | TEXT | **已确认 (冗余).** **冗余存储产品/店铺的中文名**,用于在列表页快速展示,极大提升查询性能。 |
| `prediction_scope` | TEXT (JSON) | **[新增]** 描述本次预测的范围,与 `models` 表的 `training_scope` 结构类似,指明是为哪个产品/店铺做的预测。 |
| `prediction_params` | TEXT (JSON) | **已确认.** 存储预测参数,如 `{"start_date": "...", "future_days": 7}`。 |
| `metrics` | TEXT (JSON) | **已确认 (冗余).** 缓存的性能指标,用于列表展示和排序。 |
| `result_file_path` | TEXT | **[已采纳您的规范]** 指向预测结果JSON文件的**相对路径**。文件存储在 `saved_predictions/` 目录下,并根据模型名和时间戳命名,例如:`saved_predictions/cnn_bilstm_attention_global_sum_v6_pred_20250724111600.json`。 |
| `created_at` | DATETIME | **已确认.** 记录的创建时间。 |
| `model_version` | TEXT |