2. 金融数据特征
在金融湖仓中,数据建模从来不是“把表建出来”这么简单。金融业务同时存在四类差异极大的数据:交易数据、行情数据、客户数据、风控数据。它们的时间语义、更新频率、一致性要求、合规约束各不相同,如果直接套用同一套建模范式,往往会在查询性能、数据质量或审计合规上付出代价。理解这四类数据的特征,是设计 Iceberg 表结构、分区策略、快照管理和增量管道的前提。
一、四类数据的核心特征对比
先建立整体认知。下表从时间语义、写入模式、更新频率、一致性要求、典型查询和 Iceberg 建模关注点六个维度进行归纳。
| 维度 | 交易数据 | 行情数据 | 客户数据 | 风控数据 |
|---|---|---|---|---|
| 时间语义 | 业务发生时间 + 入账时间 | 事件时间,毫秒/微秒级 | 缓慢变化,生效/失效区间 | 事件时间 + 决策时间 |
| 写入模式 | 高频追加,偶发冲正 | 持续流式追加 | 批量合并、维度更新 | 追加 + 状态回写 |
| 更新频率 | 中高,按日/实时 | 极高,毫秒级 | 低,按日/按批 | 中,按事件触发 |
| 一致性要求 | 强,需可对账 | 最终一致,允许乱序 | 强,需版本可追溯 | 强,需决策可复现 |
| 典型查询 | 账户流水、日终对账 | K线、盘口、指标计算 | 客户360、标签圈选 | 规则命中、案件回溯 |
| Iceberg 关注点 | 分区裁剪、行级删除 | 小文件合并、排序聚簇 | SCD2、快照隔离 | 血缘、时间旅行、审计 |
二、核心原理:为什么四类数据不能共用一套建模
交易数据的本质是“事实不可变、状态可修正”。一笔支付在 T 日入账,T+1 可能发生冲正或退款,因此建模上既要保留原始事实,又要能表达修正关系。Iceberg 的 MERGE INTO 与行级删除能力,使其可以在不重写全表的前提下完成冲正标记。
行情数据的本质是“高吞吐、时间有序、允许乱序到达”。逐笔成交和盘口快照每秒可达数万条,若按天分区会产生大量小文件,必须结合排序聚簇与定时 compaction。其查询多为时间窗口聚合,因此分区应优先按交易时段或小时切分。
客户数据的本质是“缓慢变化维度”。客户等级、风险评级、联系方式会随时间变化,建模需采用 SCD2 保留历史版本,否则风控回溯时无法还原当时的客户状态。
风控数据的本质是“决策可复现”。一条规则命中记录必须能回答:当时用了哪版规则、哪版客户画像、哪笔交易。这要求风控表与客户表、交易表之间具备明确的时间对齐关系,Iceberg 的快照与时间旅行正好提供了这种可追溯能力。
三、方法流程:从特征到 Iceberg 建模决策
面对一类金融数据,建议按以下流程完成建模决策:
- 识别时间语义:区分事件时间、入账时间、决策时间,确定分区字段与排序字段。
- 判断更新模式:追加、合并、回写还是删除,决定使用 append、merge 还是 delete 文件。
- 评估数据量级:日增行数、单行宽度、保留周期,决定分区粒度与文件目标大小。
- 明确一致性要求:是否需要可对账、可复现、可审计,决定是否启用快照保留与标签。
- 设计查询路径:按最常用查询确定聚簇键,避免全表扫描。
- 配置维护策略:设置 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 或快照。
- 误区三:交易表忽略冲正关系。只追加不标记,会导致对账口径混乱。
- 误区四:风控表不记录规则版本。规则升级后无法复现历史决策。
- 误区五:忽视快照过期策略。快照保留过久会拖慢元数据,过短则失去回溯能力。
综上,交易、行情、客户、风控四类数据在金融湖仓中扮演不同角色,建模时必须分别对待。交易重分区与修正,行情重排序与合并,客户重版本与快照,风控重血缘与可复现。只有把数据特征转化为具体的 Iceberg 表属性、分区策略和维护动作,湖仓才能真正支撑金融业务的对账、风控与审计需求。