前言

统计报表是企业系统里的高频场景,比如:

  • 日活、月活。
  • 订单数、成交额。
  • 转化率、复购率。
  • 渠道统计。
  • 部门报表。
  • 经营大屏。

面试常问:

  • 为什么不能每次直接查库算。
  • 统计口径怎么统一。
  • 实时统计和离线统计怎么配合。
  • 怎么保证报表性能和准确性。

统计系统的核心问题

统计系统本质上要解决三个问题:

  1. 口径一致。
  2. 计算高效。
  3. 数据可追溯。
flowchart TD
    A[业务事件] --> B[实时聚合]
    A --> C[离线明细]
    B --> D[实时大盘]
    C --> E[离线报表]
    B --> F[缓存/宽表]
    C --> G[数仓/OLAP]

为什么不能直接查库统计

直接在 OLTP 数据库上做复杂统计会遇到:

  • 扫描大表。
  • 聚合慢。
  • 锁和 IO 压力大。
  • 影响线上交易。

适合简单小范围查询,不适合全站经营统计。

统计架构怎么选

方案一:在线实时查询

直接查业务库或业务视图。

优点:

  • 实现快。

缺点:

  • 性能差。

适合:

  • 小范围后台查询。

方案二:预计算汇总

把统计指标提前算好,写入汇总表或缓存。

优点:

  • 查询快。

缺点:

  • 口径和补数复杂。

适合:

  • 经营报表。

方案三:实时流式统计

业务事件进入 MQ 或流处理系统,实时聚合后输出指标。

优点:

  • 接近实时。

缺点:

  • 架构复杂。

适合:

  • 实时大屏、运营监控。

方案四:离线数仓/OLAP

把明细数据同步到 ClickHouse、Doris、Hive、ES 等平台。

优点:

  • 适合大规模分析。

缺点:

  • 延迟更高。

适合:

  • BI 报表、经营分析。
方案 优点 缺点 场景
在线实时查询 简单 小报表
预计算汇总 补数复杂 经营报表
实时流式统计 近实时 架构复杂 实时大屏
OLAP/数仓 强分析能力 延迟较高 分析报表

日活怎么统计

日活(DAU)通常按“当天至少活跃一次的用户数”定义。

常见做法:

  • 按用户 ID 去重。
  • 按天分区。
  • 用布隆过滤器、Redis Set、Bitmap 或数仓去重统计。

对比:

方案 优点 缺点
Redis Set 简单直观 占内存大
Bitmap 空间效率高 需要映射用户 ID
数仓去重 适合大规模分析 延迟高

订单统计怎么做

订单统计一般会分多个维度:

  • 时间。
  • 渠道。
  • 地区。
  • 商品。
  • 订单状态。
  • 支付方式。

常见思路:

  1. 订单事件落库。
  2. 通过 MQ 送入统计系统。
  3. 统计库按天、小时、渠道聚合。
  4. 报表页面直接查汇总表。

预计算和宽表

预计算适合读多写少的统计指标。

例如:

  • 每小时订单数。
  • 每天支付金额。
  • 每个渠道转化率。

宽表适合把多个维度提前展开,减少查询时 join 成本。

优点:

  • 查询快。
  • 适合报表。

缺点:

  • 写入和维护成本高。
  • 口径变更麻烦。

实时汇总怎么做

实时统计通常依赖事件驱动:

  • 业务服务发事件。
  • MQ 消费聚合。
  • Redis 或流系统做滚动窗口统计。
  • 定时任务做对账和补数。
sequenceDiagram
    participant B as 业务服务
    participant M as MQ
    participant S as 统计服务
    participant R as Redis/OLAP

    B->>M: 订单支付事件
    M->>S: 消费事件
    S->>R: 更新汇总指标
    S->>R: 记录可回补明细

统计口径怎么统一

统计系统里最难的是“口径”。

例如“成交额”可能有不同定义:

  • 按支付成功算。
  • 按已完成算。
  • 是否包含退款。
  • 是否包含优惠券抵扣。

面试要强调:

统计报表不是单纯技术问题,首先是业务定义问题。没有统一口径,再快的系统算出来的数字也没有价值。

补数和对账

实时统计系统通常都需要补数。

补数场景:

  • MQ 消费失败。
  • 统计逻辑变更。
  • 历史数据修正。
  • 对账发现差异。

常见手段:

  • 按日期重跑。
  • 按事件重放。
  • 按分区补算。
  • 按批次修正。

高频面试题

为什么统计报表不能直接查业务库?

因为统计通常是聚合型查询,会扫描大量数据,容易影响核心交易库性能。

为什么要预计算?

因为报表大多是读多写少,提前算好可以把查询时间从秒级甚至分钟级降到毫秒级。

实时统计和离线统计怎么配合?

实时统计负责大屏和即时指标,离线统计负责准数据、复杂分析和历史分析。

统计口径为什么重要?

因为同一个指标可能有多个业务定义,口径不统一会导致系统之间数字对不上。

统计数据错了怎么修?

通常靠事件重放、分区重算、补数任务和对账机制修正。

总结

统计报表场景回答可以围绕五条主线:

  1. 为什么不能直接查库统计。
  2. 怎么做预计算和汇总。
  3. 怎么做实时统计。
  4. 怎么统一口径和补数。
  5. 怎么在 OLTP、缓存、MQ、OLAP 之间分工。

企业报表系统的关键不是“算出一个数”,而是把这个数算得快、算得准、算得可追溯。