3. 历史项目数据模型:核心表结构设计

特征工程成本估算系统的数据底座由四张核心维度/事实表构成:历史项目数据表、特征维度表、成本事实表和时间维度表。四表通过外键关联,形成星型模型,支撑按项目、特征、时间三个维度对成本进行聚合与下钻分析。

设计原则:维度表尽量宽(包含描述性属性),事实表尽量窄(只存度量与外键)。本模型遵循 Kimball 维度建模方法论,确保查询性能与扩展性。

3.1 历史项目数据表(dim_project)

记录每个历史项目的静态属性,是特征工程成本分析的入口维度。

字段名 类型 主键/外键 说明
project_id BIGINT PK 项目唯一标识,自增或雪花ID
project_name VARCHAR(128) — 项目名称,如“风控模型V3”
domain VARCHAR(64) — 业务域:风控/推荐/NLP/视觉
data_scale VARCHAR(32) — 数据规模等级:小/中/大/超大
source_system VARCHAR(64) — 数据来源系统,如“离线数仓”
create_time DATETIME — 项目创建时间
is_active TINYINT — 1=有效,0=已归档

3.2 特征维度表(dim_feature)

描述每个特征的元数据,包括特征类型、计算复杂度、依赖关系等,是成本估算的核心粒度。

字段名 类型 主键/外键 说明
feature_id BIGINT PK 特征唯一标识
feature_name VARCHAR(128) — 特征名称,如“用户近30天消费均值”
feature_type VARCHAR(32) — 数值型/类别型/文本型/时序型
complexity_level TINYINT — 计算复杂度:1~5,5最高
dependency_cnt INT — 依赖上游特征/表数量
avg_compute_ms DECIMAL(10,2) — 历史平均单次计算耗时(ms)
storage_bytes BIGINT — 特征存储占用字节数

3.3 成本事实表(fact_cost)

存储每个项目、每个特征、在每个时间周期内的实际成本度量,是分析模型的事实主体。

字段名 类型 主键/外键 说明
cost_id BIGINT PK 事实记录唯一标识
project_id BIGINT FK → dim_project 关联项目
feature_id BIGINT FK → dim_feature 关联特征
time_id INT FK → dim_time 关联时间
compute_cost DECIMAL(12,4) — 计算成本(CPU/GPU 折算金额)
storage_cost DECIMAL(12,4) — 存储成本(按GB/天折算)
io_cost DECIMAL(12,4) — IO成本(读写吞吐折算)
total_cost DECIMAL(12,4) — compute_cost + storage_cost + io_cost
record_date DATE — 成本发生日期(冗余字段,加速查询)

3.4 时间维度表(dim_time)

提供日期、周、月、季度、年等时间层次,支持按不同粒度汇总成本。

字段名 类型 主键/外键 说明
time_id INT PK 日期整数键,格式 YYYYMMDD
full_date DATE — 标准日期
year SMALLINT — 年份,如 2025
quarter TINYINT — 季度:1~4
month TINYINT — 月份:1~12
week_of_year TINYINT — 年内第几周:1~53
day_of_week TINYINT — 周几:1=周一,7=周日
is_weekend TINYINT — 1=周末,0=工作日

3.5 星型模型关系图

四张表通过外键关联,形成标准的星型数据模型,便于 OLAP 查询与成本聚合。

历史项目成本星型模型 fact_cost cost_id (PK) project_id (FK) feature_id (FK) time_id (FK) | total_cost dim_project project_id (PK) project_name | domain dim_feature feature_id (PK) feature_name | complexity dim_time time_id (PK) full_date | year | month 模型特点 星型结构,维度退化 支持按项目/特征/时间 多维聚合分析 project_id feature_id time_id

3.6 核心查询场景示例

基于上述模型,以下 SQL 查询按项目+月份聚合总成本,是成本估算接口的典型数据源:

SELECT
    p.project_name,
    t.year,
    t.month,
    ROUND(SUM(f.total_cost), 2) AS total_cost_sum
FROM fact_cost f
JOIN dim_project p ON f.project_id = p.project_id
JOIN dim_time t ON f.time_id = t.time_id
WHERE p.is_active = 1
  AND t.year = 2025
GROUP BY p.project_name, t.year, t.month
ORDER BY total_cost_sum DESC;
性能提示:fact_cost 表按 (project_id, time_id) 建立联合索引,可加速按项目+时间范围的过滤查询。dim_feature 的 complexity_level 字段建议加索引,用于按复杂度筛选特征子集。

3.7 数据模型版本管理建议

  • 缓慢变化维度(SCD):dim_feature 中 avg_compute_ms 和 storage_bytes 可能随版本更新,建议采用 SCD Type 2(增加生效时间区间)或 Type 6(混合模式)记录历史。
  • 事实表增量加载:fact_cost 按 record_date 分区,每日增量写入,避免全表扫描。
  • 维度表预填充:dim_time 一次性生成 10 年数据,减少运行时计算。
避坑提醒:不要在 fact_cost 中冗余存储 project_name 或 feature_name,保持事实表轻量。维度属性变更时只需更新维度表,无需修改事实表。