前面的文章我们讲了一种简易的数仓分层设计,然后聊了聊在数仓 DW 层可以使用的维度建模方法,现在我们有了一堆建模完成的数据,但实际上这些数据只是进行了从 OBS 层的“收集”走到了 DW 的“整理”,也就是我们大部分的数据还是业务系统已有的内容,并没有让数据产生更多的价值,让我们来继续以超市为例在看看数据的背后隐藏了什么。
指标是什么
指标以一定的固定的规则分析得到的数据,用以衡量指定的目标。那继续我们之前的例子:
2020.03.15 小明买了 10 个苹果,共计 3 斤,5.7 元 / 斤;3 斤橘子,4.00 元 / 斤;2 桶 1.5 L 的 XX 牌矿泉水,3.00 元 / 桶;一袋米 30 元
2020.03.15 小红买了一包约 3 斤的菠菜 共 10 元;5 斤土豆 2.0 元 / 斤,2 斤橘子,4.00 元 / 斤
为了进行指标的说明,我们扩充了一下例子,上面就是我们当天的两个订单了,315 的日子价格还算靠谱可惜只有两个人来买东西
让我们的指标开始建立,第一个指标:
- 第一个指标:一个订单的各类总价及订单总价,存上这两个数据:2020.03.15 小明购买的总价、蔬菜类总价、水果类总价、饮品类总价;2020.03.15 小红订单够买的总价、蔬菜类总价、水果类总价、饮品类总价
-
第二个指标:日销售额指标:因为 2020.03.15 只有两笔订单,所以这一天的销售额就是两笔订单的总价了,这个指标一天只记录一条
……
根据复杂的业务数据我们可以构建各种各样的指标,并把他们的计算结果s存到 table 中以供直接使用,这样复杂的计算过程就在指标这一层完成了,后续的无论是报表还是单独查看某一指标都可以直接拿来就用
指标的分层
看一下上面一小节提到的订单总价指标、日销售额指标,这两个实际上是有层次关系的,我们的日销售额完全可以直接使用订单总价指标一天的价格直接求和得到,就不需要对订单里每个条目完整计算一遍了。这样就构成了指标之间的依赖关系 / 层次关系。
指标数量繁多,但总的来说可以分为两类:基础指标、计算指标,对于订单总价可以算是基础指标,对于日销售额可以算是计算指标。
除此以外对于指标的分层可以以 原子指标、衍生指标、复合指标三大类型进行区分
原子指标
由业务、业务过程、度量值构成,比如:
- 业务:钱包、账号、游戏中心、音乐、阅读、购物……
-
业务过程:登录、浏览、支付、下载、安装、聊天、点单……
-
度量:用户数、设备数、次数、时长、金额……
把他们凑到一起:对于钱包业务我们可以统计登录用户数,购物业务可以统计点单次数、阅读浏览市场……
衍生指标
由原子指标 + 业务规则、修饰词构成,比如:
业务规则:新增、回访、留存、流失……
修饰词:关键词、热词、现金、单聊、群聊、组合订单、跨店……
再来几个例子:对于音乐业务新增用户数量、在线客服业务的与单一客服能解决问题的聊天时长、双十一期间购物业务的新增跨店支付用户数
复合指标
由衍生指标 + 计算规则构成,比如:
计算规则:同比增长、环比增长……
双十一购物业务的新增跨店支付用户数的同比增长率、新增智能在线客服业务功能后,单一客服解决问题时的聊天时长的环比下降率
我们通过逐层的进行业务梳理、规则抽取最终得到一组层次分明、可复用性强的指标集
维度与指标
我们的维度也是可以分层的:原子维度、衍生维度……比如日期可以衍生出月份、季度、年份,上一篇文章重点说了时间维度的事情,对于缓慢变化维来说是可能产生指标的:
如果不幸的事情发生了:我们超市的系统设计成了一个订单可以重复的结账退账,用户在结账后发现商品过期了这个时候选择退账,然后主管来输入密码又可以让用户在一个订单里更换一个未过期的批次较新的商品……
这样按照缓慢变化维来说我们对于这个订单号会有最少两个结账状态记录,难道我们要每次使用到这个维度的时候都要秀一波对程序猿对时间的敏感性?
这个时候如果我们大部分指标更关注一个状态最后一次的发生时间时,我们可以针对这个维度创建相应的指标:最近的结账日期指标、最近的退账日期指标、最近的订单状态、结账次数、退账次数……
这样我们通过这样的一个指标就把我们比较关注的信息都计算出来并存到了这个 / 这些指标表中,后续的指标其他指标计算就可以放心使用了
报表与指标
报表实际上是明细信息与指标值的集合,我们的报表往往具有:fact 表的一些明细字段、多个指标表的指标值。
这个时候我们可以通过 ETL 工具将多个表的数据 join 到一起,并输出最终的报表 table,以供后端服务仅通过一次并不复杂的查询来拿到数据,以保证报表数据获取的高效性。
当然我们也可以通过数据库的视图来完成上面的 join 操作,此时 ETL 工具只需要做 view 到 table 的拷贝操作,可以降低 ETL 操作量,并降低对单一 ETL 工具的依赖。
注意事项
让我们来聊聊实现的细节,仅为个人经验不一定适用于所有项目:
- 用的一定是指标表:提供一个存储指标计算结果的 table 给任何其他指标、报表等等使用,一定要是 table,一定要是一个 table,一定要是一个 table。因为每个指标都是复杂的逻辑计算出来的,不要让其他功能去调用我们的运算逻辑(无论是数据库里的视图还是存储过程),直接给其结果,否则每次都要进行复杂计算。包括在多层指标之间也不要互相调用逻辑
-
去除重复,逻辑复用不适用:当有多个指标使用了同一个逻辑的时候,考虑这个逻辑是否应该提取出来一个具有其特有业务意义的指标,并将其计算结果存储到指标表中以供多个更高层指标使用
-
增量计算:指标计算复杂性高,尤其是在数据量庞大时,请适当考虑增量计算。由于每个指标都存储到了 table 中,我们可以在计算过程中只计算增量的信息,然后 upsert 到最终的 table,以保证指标表中数据的完整性。同时降低了算力的需求 — 省钱。如何做增量改造?请看后续文章
-
一个指标表,不止一个指标值,相同类型的且计算方式可共用的指标值完全可以放在一个指标表中,比如上面的例子中将一个订单的蔬菜类总价、水果类总价、饮品类总价等指标放在了一起,这样可以在遍历一次订单项表就算出多个指标值,对于没有相关物品的订单可以写 0.0
- 特别留意 null 的问题,既然存到了表中就要明确的确定 null 是 0.0 还是有其独有的意义,比如”null 说明还未到产生价格的阶段”
前面提到 ETL 是什么?怎么做到增量计算?事实、维度、指标有没有设计思路?篇幅有限请见后续文章
感谢阅读,欢迎关注微信公众号:coologic
报表相关的系列文章请参考:
| 版权声明: 本站文章采用 CC 4.0 BY-SA 协议 进行许可,转载请附上原文出处链接和本声明。
| 本文链接: Cologic Blog - 报表自动化: 薅出数字背后的价值 - https://www.coologic.cn/2020/03/1769/