2. 金融数据特征

在金融湖仓中,数据建模从来不是“把表建出来”这么简单。金融业务同时存在四类差异极大的数据:交易数据、行情数据、客户数据、风控数据。它们的时间语义、更新频率、一致性要求、合规约束各不相同,如果直接套用同一套建模范式,往往会在查询性能、数据质量或审计合规上付出代价。理解这四类数据的特征,是设计 Iceberg 表结构、分区策略、快照管理和增量管道的前提。

一、四类数据的核心特征对比

先建立整体认知。下表从时间语义、写入模式、更新频率、一致性要求、典型查询和 Iceberg 建模关注点六个维度进行归纳。

维度 交易数据 行情数据 客户数据 风控数据
时间语义 业务发生时间 + 入账时间 事件时间,毫秒/微秒级 缓慢变化,生效/失效区间 事件时间 + 决策时间
写入模式 高频追加,偶发冲正 持续流式追加 批量合并、维度更新 追加 + 状态回写
更新频率 中高,按日/实时 极高,毫秒级 低,按日/按批 中,按事件触发
一致性要求 强,需可对账 最终一致,允许乱序 强,需版本可追溯 强,需决策可复现
典型查询 账户流水、日终对账 K线、盘口、指标计算 客户360、标签圈选 规则命中、案件回溯
Iceberg 关注点 分区裁剪、行级删除 小文件合并、排序聚簇 SCD2、快照隔离 血缘、时间旅行、审计

二、核心原理:为什么四类数据不能共用一套建模

交易数据的本质是“事实不可变、状态可修正”。一笔支付在 T 日入账,T+1 可能发生冲正或退款,因此建模上既要保留原始事实,又要能表达修正关系。Iceberg 的 MERGE INTO 与行级删除能力,使其可以在不重写全表的前提下完成冲正标记。

行情数据的本质是“高吞吐、时间有序、允许乱序到达”。逐笔成交和盘口快照每秒可达数万条,若按天分区会产生大量小文件,必须结合排序聚簇与定时 compaction。其查询多为时间窗口聚合,因此分区应优先按交易时段或小时切分。

客户数据的本质是“缓慢变化维度”。客户等级、风险评级、联系方式会随时间变化,建模需采用 SCD2 保留历史版本,否则风控回溯时无法还原当时的客户状态。

风控数据的本质是“决策可复现”。一条规则命中记录必须能回答:当时用了哪版规则、哪版客户画像、哪笔交易。这要求风控表与客户表、交易表之间具备明确的时间对齐关系,Iceberg 的快照与时间旅行正好提供了这种可追溯能力。

关键结论:交易与行情是“事实流”,客户是“维度流”,风控是“决策流”。事实流重分区与合并,维度流重版本与合并,决策流重血缘与快照。

三、方法流程:从特征到 Iceberg 建模决策

面对一类金融数据,建议按以下流程完成建模决策:

  1. 识别时间语义:区分事件时间、入账时间、决策时间,确定分区字段与排序字段。
  2. 判断更新模式:追加、合并、回写还是删除,决定使用 append、merge 还是 delete 文件。
  3. 评估数据量级:日增行数、单行宽度、保留周期,决定分区粒度与文件目标大小。
  4. 明确一致性要求:是否需要可对账、可复现、可审计,决定是否启用快照保留与标签。
  5. 设计查询路径:按最常用查询确定聚簇键,避免全表扫描。
  6. 配置维护策略:设置 compaction、expire snapshots、manifest 重写周期。

以交易数据为例,一个典型的 Iceberg 建表与合并配置如下:

CREATE TABLE lake.txn_detail (
  txn_id        STRING,
  account_id    STRING,
  event_time    TIMESTAMP,
  settle_time   TIMESTAMP,
  amount        DECIMAL(18,2),
  status        STRING,
  is_reversed   BOOLEAN
)
USING iceberg
PARTITIONED BY (days(settle_time), bucket(16, account_id))
TBLPROPERTIES (
  'write.target-file-size-bytes' = '134217728',
  'write.merge.mode' = 'copy-on-write',
  'history.expire.max-snapshot-age-ms' = '604800000'
);

行情数据则更强调排序与合并:

ALTER TABLE lake.market_tick
WRITE ORDERED BY (symbol, event_time);

CALL lake.system.rewrite_data_files(
  table => 'lake.market_tick',
  strategy => 'sort',
  sort_order => 'symbol, event_time'
);

四、案例场景:一次风控回溯暴露的建模问题

某机构在复盘一笔异常交易时发现,风控系统当时判定为“低风险”,但事后用当前客户评级重新计算却显示“高风险”。排查后发现,客户表采用了覆盖式更新,历史评级被直接覆盖,导致无法还原决策时点的客户状态。修复方案是将客户表改为 SCD2 结构,并在风控决策表中记录 customer_version 与 rule_version,同时利用 Iceberg 快照按决策时间进行时间旅行查询。

SELECT *
FROM lake.risk_decision FOR SYSTEM_TIME AS OF '2024-06-01 09:30:00'
WHERE case_id = 'C20240601001';

这个案例说明:风控数据的建模挑战不在数据量,而在“时间对齐”和“版本可追溯”。如果客户维度没有版本,风控决策就失去了可复现性。

实践建议:对客户、规则、产品等维度统一采用 SCD2,并在所有事实表中冗余版本号字段,可在不依赖时间旅行的情况下快速还原决策上下文。

五、常见误区与复盘

  • 误区一:所有数据都按天分区。行情数据按天分区会产生海量小文件,应按小时或交易时段分区。
  • 误区二:客户表直接覆盖更新。会破坏风控与审计的可追溯性,应使用 SCD2 或快照。
  • 误区三:交易表忽略冲正关系。只追加不标记,会导致对账口径混乱。
  • 误区四:风控表不记录规则版本。规则升级后无法复现历史决策。
  • 误区五:忽视快照过期策略。快照保留过久会拖慢元数据,过短则失去回溯能力。
复盘要点:金融湖仓建模的第一原则是“时间与版本可追溯”。任何覆盖式更新、无版本维度、无快照保留的设计,都会在审计或风控回溯时成为隐患。
金融四类数据特征与 Iceberg 建模关注点 交易数据 事实不可变 状态可修正 需可对账 分区裁剪 + 行级删除 行情数据 高吞吐流式 时间有序 允许乱序 排序聚簇 + 小文件合并 客户数据 缓慢变化维度 版本可追溯 强一致性 SCD2 + 快照隔离 风控数据 决策可复现 规则版本化 强审计要求 血缘 + 时间旅行 Apache Iceberg 湖仓建模层 分区 · 快照 · 合并 · 时间旅行 · 血缘 分区与聚簇 裁剪扫描范围 快照与版本 支撑回溯审计 合并与删除 处理冲正与更新 时间旅行 复现历史决策

综上,交易、行情、客户、风控四类数据在金融湖仓中扮演不同角色,建模时必须分别对待。交易重分区与修正,行情重排序与合并,客户重版本与快照,风控重血缘与可复现。只有把数据特征转化为具体的 Iceberg 表属性、分区策略和维护动作,湖仓才能真正支撑金融业务的对账、风控与审计需求。