3. 数据聚合层核心概念
在风险数据体系建设中,源系统负责“产生交易”,风险数据集市负责“消费指标”,而两者之间往往存在巨大的语义鸿沟与性能鸿沟。数据聚合层正是填补这道鸿沟的关键中间层。理解聚合层的定义、边界与设计原则,是后续所有建模与开发工作的前提。
一、聚合层的定义与本质
数据聚合层(Data Aggregation Layer,简称聚合层)是位于源系统与风险数据集市之间、以“面向风险主题的整合与轻量汇总”为核心职责的逻辑数据层。它并不追求企业级数据仓库的全域一致性,而是聚焦风险条线所需的客户、协议、担保、额度、交易、评级等核心实体,完成清洗、标准化、关联与预聚合。
聚合层的本质可以概括为三点:
- 语义转换器:把源系统的技术字段(如
CUST_NO、ACCT_ID)翻译为风险业务可理解的统一实体(客户、协议、敞口)。 - 性能缓冲带:通过预关联与预汇总,把集市层复杂的多表关联计算前移,降低集市查询压力。
- 变更隔离墙:源系统结构变化时,只需调整聚合层映射,集市与下游报表保持稳定。
核心判断标准:如果一个数据加工步骤同时被两个以上风险集市复用,或涉及跨源系统整合,它就应该下沉到聚合层,而不是留在集市内部。
二、聚合层与源系统、集市的关系
三者构成“产生—整合—消费”的链路。源系统是事实的发生地,聚合层是事实的整理地,集市是事实的呈现地。可以用下面的结构关系来理解它们在数据流中的位置与职责分工。
需要强调的是,聚合层不是“小数据仓库”。数据仓库追求全域一致与历史追溯,聚合层只服务风险条线,允许一定程度的冗余与场景化设计,但必须保证同一实体在聚合层内口径唯一。
三、逻辑架构与分层原则
聚合层内部通常再细分为三个子层,形成清晰的加工梯度:
| 子层 | 核心职责 | 典型对象 | 更新策略 |
|---|---|---|---|
| 贴源整合层 | 字段标准化、编码映射、去重 | 客户主键、协议主键 | 日增量 |
| 主题关联层 | 跨源关联、实体拉链、关系构建 | 客户-协议-担保关系 | 日全量/拉链 |
| 轻量汇总层 | 敞口、额度、余额预汇总 | 客户级敞口、产品级余额 | 日快照 |
分层设计应遵循四条原则:
- 单一实体单一入口:同一客户或协议在聚合层只允许一个权威来源,避免多头加工。
- 加工下沉、消费上浮:越通用的加工越靠下,越贴近报表的加工越靠上。
- 可追溯:每个汇总值都能回溯到贴源明细,保留血缘关系。
- 幂等与可重跑:同一批次重复执行结果一致,便于故障恢复。
实践建议:聚合层的表命名应体现子层与主题,例如
agg_cust_exposure_d、agg_agr_limit_d,让下游一眼识别数据来源与粒度。
四、常见术语与典型误区
在项目沟通中,以下术语出现频率最高,需要统一理解:
- 实体(Entity):风险关注的对象,如客户、协议、担保、押品。
- 粒度(Grain):一行数据代表的业务含义,如“一个客户一天一条”。
- 拉链(Zipper):用起止日期记录实体状态变化的历史技术。
- 敞口(Exposure):风险暴露金额,是聚合层最核心的汇总指标。
- 血缘(Lineage):字段从源到集市的加工路径。
常见误区一:把聚合层当成“临时表区”,随意建表、不管理口径,导致下游集市各自为政。
常见误区二:在聚合层做过度汇总,丢失明细,导致集市无法下钻。
常见误区三:忽略拉链与历史,只保留最新状态,监管追溯时无法还原。
常见误区二:在聚合层做过度汇总,丢失明细,导致集市无法下钻。
常见误区三:忽略拉链与历史,只保留最新状态,监管追溯时无法还原。
一个典型场景:某银行信用风险集市需要“客户级表内外敞口”。若直接在集市内关联核心、信贷、信用卡三套系统,SQL 超过 800 行且每日跑批超时。引入聚合层后,先在贴源整合层统一客户号,再在主题关联层构建客户-协议关系,最后在轻量汇总层按客户汇总敞口。集市只需读取一张宽表,跑批时间下降约 60%,且口径变更只需修改聚合层一处。
-- 聚合层轻量汇总示例:客户级敞口日快照
INSERT OVERWRITE TABLE agg_cust_exposure_d PARTITION (dt='2024-06-30')
SELECT
c.cust_id,
SUM(CASE WHEN a.balance_type='ON' THEN a.balance ELSE 0 END) AS on_bal_exposure,
SUM(CASE WHEN a.balance_type='OFF' THEN a.balance ELSE 0 END) AS off_bal_exposure,
SUM(a.balance) AS total_exposure
FROM agg_cust_agr_rel_d r
JOIN dim_cust c ON r.cust_id = c.cust_id
JOIN agg_agr_balance_d a ON r.agr_id = a.agr_id
WHERE r.status = 'A'
GROUP BY c.cust_id;