订阅更新

时区、币种、汇率怎么处理?——出海业务的指标坑

指标管理手册 第 9 题 约 9 分钟读完

本文目录
  1. 先说结论
  2. 业务场景:DAU按UTC统计错把跨日用户漏掉
  3. 方法一:3个时间字段+时区维度
  4. 方法二:币种和汇率的标准做法
  5. 方法三:汇率快照表的设计
  6. 方法四:跨时区聚合的「全球vs本地」双视角
  7. 面试高频追问
  8. 实战踩坑:印度卢比汇率10%日波动导致GMV趋势误判
  9. 总结

先说结论

出海指标的3大坑:①时区:用户当地时区 vs UTC vs 公司总部时区,DAU能差15% ②币种:本币 vs USD折算 vs 报告币种,财务对账经常错 ③汇率:用日均/月均/锁定汇率,影响GMV趋势分析。每个坑都有对应解法,关键是把维度独立成字段。

治理核心是「数据存原始+计算时折算」。原始数据保留本币、本地时间,计算指标时按场景折算成报告维度。不要在ETL早期就折算,否则后期想换维度就重跑。

出海业务必备的3张表:①时区映射表(country→timezone)②汇率快照表(每日各币种→USD汇率)③地区维度表(含国家、大区、监管区域)。这三张表不齐全,所有出海指标都是水中楼阁。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

出海业务的指标管理比国内业务复杂10倍——光时区一个维度就能让你的「日活」「GMV」错得离谱。我在某出海硬件品牌和某短剧出海公司前后做过6年出海数据,踩遍了时区/币种/汇率所有的坑。这道题但凡你能讲清楚3个坑+解决方案,就比90%候选人答得好。出海企业现在面试很爱问这道。

业务场景:DAU按UTC统计错把跨日用户漏掉

出海硬件品牌覆盖80+国家。最早我们的DAU按UTC时区算——结果美国西部用户的"当地夜晚活跃"(UTC的下午)和"次日白天活跃"(UTC的次日凌晨)会被算成两次活跃,但其实是同一个用户的连续行为。

更糟的是欧洲用户的DST(夏令时)切换日,那一天部分时间出现26小时或22小时,数据全乱。CEO看周报时美国用户DAU陡降8%,以为是产品出问题,连开三个紧急会,最后发现是DST切换。

-- 错误做法:直接按UTC日期
SELECT DATE(login_time_utc) AS dt, COUNT(DISTINCT user_id) AS dau
FROM ods_login WHERE login_time_utc >= '2023-03-12'
GROUP BY DATE(login_time_utc);
-- 问题:3月12日是美国DST切换日,UTC日期下美国用户的「当地一天」错位
 
-- 正确做法:按用户当地时区算「当地日期」
SELECT user_local_date AS dt, COUNT(DISTINCT user_id) AS dau
FROM (
  SELECT user_id,
         DATE(CONVERT_TZ(login_time_utc, 'UTC', tz.timezone))
           AS user_local_date
  FROM ods_login l
  LEFT JOIN dim_country_timezone tz ON l.country = tz.country_code
) t GROUP BY user_local_date;

方法一:3个时间字段+时区维度

出海业务的事实表必须有3个时间字段,不要只存一个:

字段名含义用途示例
event_time_utc事件UTC时间戳全局排序、跨时区对比2023-03-12 08:30:00 UTC
event_time_local用户当地时间按用户当地日期统计2023-03-12 01:30:00 PST
event_dt_local用户当地日期按当地天聚合2023-03-12
timezone时区标识审计追踪、DST处理America/Los_Angeles

关键:不要只存UTC再每次CONVERT_TZ——耗费资源且容易写错。在ETL时一次性算好这3个字段+时区,下游直接用。

方法二:币种和汇率的标准做法

出海业务的金额必须存3个币种字段,由ETL层一次性算好:

-- 订单事实表的金额字段设计
CREATE TABLE dwd_order_pay (
  order_id          BIGINT,
  -- 原始本币(永远不动)
  pay_amount_local  DECIMAL(18,2),
  currency          VARCHAR(8),       -- USD/EUR/JPY/INR...
  -- USD折算(用支付当日汇率)
  pay_amount_usd    DECIMAL(18,2),
  fx_rate_to_usd    DECIMAL(18,6),    -- 用了哪个汇率
  fx_rate_date      DATE,             -- 用的哪天的汇率
  -- 报告币种(如人民币)
  pay_amount_cny    DECIMAL(18,2),
  fx_rate_to_cny    DECIMAL(18,6),
  pay_time_utc      TIMESTAMP
) PARTITIONED BY (dt);

3个币种独立字段+ ETL时锁定汇率,避免下游每次自己折算。fx_rate_date字段可以让审计很容易回溯"这条订单当时用了哪天的汇率"。

方法三:汇率快照表的设计

汇率本身就是一张表。要点:每日全量、不可变、来源明确:

CREATE TABLE dim_fx_rate_daily (
  fx_date         DATE,                     -- 汇率日期
  from_currency   VARCHAR(8),
  to_currency     VARCHAR(8),
  rate            DECIMAL(18,6),
  source          VARCHAR(32),              -- ECB/Open Exchange Rates
  source_time_utc TIMESTAMP,
  is_locked       BOOLEAN DEFAULT TRUE,    -- 锁定后不可改
  PRIMARY KEY (fx_date, from_currency, to_currency)
);
 
-- 三种汇率取法(按业务场景选)
-- 1. 当日中间价(订单实付折算用)
SELECT rate FROM dim_fx_rate_daily
WHERE fx_date = '2023-03-12' AND from_currency='EUR' AND to_currency='USD';
 
-- 2. 当月平均(财务月报用)
SELECT AVG(rate) FROM dim_fx_rate_daily
WHERE fx_date BETWEEN '2023-03-01' AND '2023-03-31'
  AND from_currency='EUR' AND to_currency='USD';
 
-- 3. 锁定汇率(年度预算用,由CFO指定)
SELECT 1.08 AS budget_rate;  -- 写死,对应整年预算

方法四:跨时区聚合的「全球vs本地」双视角

有些指标需要「全球视角」(按UTC日聚合),有些需要「本地视角」(按用户当地日)。我建议两个版本都跑出来:

-- 全球视角:按UTC日,全公司一个DAU(用于对外披露)
SELECT DATE(event_time_utc) AS utc_date,
       COUNT(DISTINCT user_id) AS dau_global
FROM dws_user_action_1d GROUP BY DATE(event_time_utc);
 
-- 本地视角:按用户当地日,看每个国家的真实DAU
SELECT event_dt_local AS local_date,
       country,
       COUNT(DISTINCT user_id) AS dau_local
FROM dws_user_action_1d GROUP BY event_dt_local, country;
 
-- 这两个DAU不会相等!全球视角=本地视角SUM-跨日重复

两个视角都对,但用途不同。在出海硬件品牌,对外披露用全球视角(一致性好),运营分析用本地视角(更真实反映用户行为)。

面试高频追问

追问一:DST切换日的用户行为怎么处理?

DST切换是出海业务最隐蔽的坑。3月那天"消失了1小时"(2:00直接跳到3:00),11月那天"多出1小时"(1:00-2:00跑两次)。处理原则:①事件时间用UTC存储(UTC不受DST影响)②聚合到本地日期时用Olson时区数据库(如America/Los_Angeles,自动处理DST),不要用纯offset(-08:00或-07:00)③DST切换日的小时级数据加`is_dst_transition`标记。我在出海硬件品牌DST那两天做了人工核对,平均偏差在0.3%以内是可接受的。

追问二:业务突然要看「按总部时区的DAU」,怎么快速实现?

如果按方法一存了3个时间字段+时区,30秒能写出来——只要再CONVERT_TZ一次到总部时区即可。如果只存了UTC,要重写ETL,时间长。这就是为什么要在事实表设计阶段就把时区维度独立——「设计一次、用一辈子」。我在出海硬件品牌为CEO办公室专门加过一个"按SF总部时区的DAU",5分钟搞定,他很满意。

追问三:年度GMV用什么汇率?

看用途:①对内经营分析——用每月平均汇率,月内一致 ②对外披露——按GAAP/IFRS要求,一般用月平均或日均累加 ③年度预算/KPI——CFO锁定汇率,整年不变。三种各有道理,关键是字段独立、口径文档化。出海硬件品牌的GMV报表会有3个版本:current_fx(实时汇率)、monthly_avg_fx(月均)、locked_fx(预算锁定),一目了然。

实战踩坑:印度卢比汇率10%日波动导致GMV趋势误判

某出海硬件品牌2022年印度卢比一周贬值7%,我们用「订单当日汇率」折算USD时,印度GMV看起来环比下降12%——CEO以为是印度市场出问题,差点砍预算。其实印度本币GMV是涨的,只是汇率波动导致USD口径下降。后来我们做了三件事:①对外报表同时展示本币、USD、CNY三个版本 ②高波动地区增加「汇率影响」分析项 ③CEO周报固定加一句「剔除汇率影响后...」

教训:出海企业的财务指标必须区分"业务变化"和"汇率变化"。不分清就是给CEO误导。这种细节体现的是数据团队的业务理解深度,不是技术问题。

总结

回答这道题的高分结构:先点3大坑(时区/币种/汇率)→ 给设计(3个时间字段+3个币种字段+汇率快照表)→ 给业务洞察(DST处理、汇率影响分析、双视角DAU)。强调"出海指标治理是设计驱动的,事实表多设计几个字段省后期无数返工"。能聊到DST、Olson时区库、IFRS报告币种就是Senior+。

下一篇聊偏架构的话题:维度爆炸了——一个指标拆8个维度查,OLAP撑不住——指标和维度怎么共建?

你们做出海业务踩过最坑的时区/币种问题是什么?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器