首页/数据/数仓建模速查/案例:金融账户流水与余额建模
建模基础69 条

案例:金融账户流水与余额建模

账户域三件套:交易流水事实(借贷)、日终余额快照、账户维度;金额用最小货币单位整数,借贷方向与符号约定全仓统一。

数仓建模速查数据更新于 2026-10-13

账户域的三件套

账户域的经典组合是:交易流水事实表(一笔交易一行,借方与贷方金额分开存放)、日终余额快照(账户乘以日,记录期末余额)、账户维度。流水回答发生了什么,快照回答某时点余额是多少,两者必须能勾稽:当日流水净额加上期初余额等于期末余额。

基本信息

流水粒度一笔交易一行,交易流水号唯一
快照粒度账户乘以日,一天一个账户一行
账户维度代理键、客户号、开户机构、账户类型
金额单位最小货币单位的整数(分),避免浮点误差
勾稽校验期初余额加当日净额等于期末余额

典型使用场景

  • 账户流水查询:按客户、账户与时间范围列出借贷明细
  • 日终余额报表:直接从快照取数,不必每天重算全量流水
  • 资金监控:识别大额、高频与异地异常交易
  • 计息与收费:期初余额与当日发生额是利息和手续费的计算输入
  • 审计与对账:流水与快照逐日勾稽,差异可定位到具体账户与日期

交易流水表与逐日勾稽

交易流水表与逐日勾稽
-- 借贷双向金额:dr 借方、cr 贷方,单位统一为分
CREATE TABLE fact_acct_txn (
  txn_id   string COMMENT '交易流水号',
  acct_sk  bigint COMMENT '账户代理键',
  txn_type string COMMENT '交易类型编码',
  dr_amt   bigint COMMENT '借方金额,单位分',
  cr_amt   bigint COMMENT '贷方金额,单位分',
  txn_ts   timestamp COMMENT '记账时间'
) PARTITIONED BY (dt string) STORED AS ORC;

-- 逐日勾稽:期初加当日净额必须等于期末
SELECT count(1) AS bad_cnt
FROM fact_acct_balance_daily b
LEFT JOIN (SELECT acct_sk, sum(dr_amt) - sum(cr_amt) AS net
           FROM fact_acct_txn WHERE dt = '2026-10-12' GROUP BY acct_sk) t
  ON b.acct_sk = t.acct_sk
WHERE b.dt = '2026-10-12'
  AND b.open_bal + coalesce(t.net, 0) <> b.close_bal;

流水与快照的分工

对比项交易流水日终余额快照
粒度交易笔级账户乘以日
主键交易流水号账户加日期
回答的问题发生了什么某时点有多少
数据量大,需按时间与账户归档中等,可长期保留
在勾稽中的角色当日净额来源提供期初与期末
借贷方向与正负号只能有一套约定:业务侧统一存借、贷两个非负金额,报表再派生符号,混用两套约定会在净额汇总时出现方向性错误。
金额一律用整数分存储:浮点数在小数位累积误差后勾稽会恒不成立,且这类错误难以复现,排查成本远高于改用整数。

易错点

  • 借贷方与正负号两套约定混用:净额方向算错,对账差异难以解释
  • 余额快照与流水不做勾稽:差异逐日累积,审计时已无法定位从哪天开始
  • 金额用浮点数存储:精度误差让勾稽等式永远不成立
  • 交易流水号在不同源系统重复:流水去重失效,金额虚增
  • 冲正与撤销交易当普通交易直接相加:金额被重复计入,需按类型标识区分处理

数据来源与参考

  • 金融数仓实践:账户与流水模型
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌