会议室里,有人打开销售仪表盘,上个月收入210万。另一个人打开财务仪表盘,同一个公司、同一个月、同一个词——"收入"——数字是190万。接下来的二十分钟,全屋子人在争论哪个才是对的。没人能给出确定答案。会议继续往下走,但这两个数字,谁也没真正信。
只要你在任何一家有不止一个仪表盘的公司待过,这个场景就不陌生。问题不在于谁犯了错。问题在于,大多数公司处理数据的方式,让这种结果几乎必然发生。
两个数字为什么不一样
仪表盘对不上,是因为在某个地方,两个人各自写下了"收入"的定义,而他们彼此并不知道对方的存在。
一个数字要出现在仪表盘上,得先经过一道转换。原始数据落进数据库——订单、退款、折扣、税费、失败支付、测试交易、取消的订阅。要把这堆东西变成"收入",得有人写一条SQL查询,在里面决定上百个小问题:退款算不算?折扣要不要减掉?含不含税?下了单但还没付款的订单怎么处理?当月取消的订阅,算不算这个月的?
每一个选择都会改变最终数字。而这些选择通常藏在各自的查询里,散落各处,由不同的人在不同的时间写下。销售仪表盘的查询用一种方式处理退款,财务仪表盘的查询用另一种。两个作者都合理,谁也没写下自己的假设,谁也没被复核过。于是就有了两个"收入"。
把这件事乘以公司追踪的每一个指标——"活跃用户""流失率""转化率""月度经常性收入"——你就得到了大多数公司数据的常态:一堆没有文档、没有测试、互不协调的SQL,任何一个数字的定义都散在六个地方,没人说得清哪个才算数。
数据转换,是软件里最后一块没有工程纪律的角落
想想平时怎么写应用代码。你用版本控制,每次改动都被追踪、被审查。你写测试,在用户发现之前就知道哪里坏了。你写文档,复用代码而不是复制粘贴,你有评审流程。这些习惯标准到我们根本不会去想它。
再看那条收入查询是怎么写出来的。没有版本控制——它躺在某个BI工具或某个人的本地文件里。没有测试——没人断言过"收入不该是负数"或者"每个订单应该恰好对应一个客户"。没有文档——假设全在作者脑子里。没有复用——下一个人从头写了自己那版,略有不同。没有评审——它直接上了全公司都信任的仪表盘。
多年来,数据转换就是这么运作的。整个链条的最后一步——把原始数据变成人们据以决策的数字——不具备我们在软件其他任何地方都视为理所当然的工程纪律。说出口其实挺奇怪:公司里最关乎决策的代码,恰恰是工程化程度最低的。
这个缺口,正是分析工程要填的。
分析工程到底是什么
它既是一个岗位,也是一门学科,在最近几年冒出来,卡在一个此前没人覆盖的位置上。最容易看清它的方式,是拿它和左右两边的角色对照:
- 数据工程师:搭建管道,把原始数据搬进数据仓库。这是管道工。
- 数据分析师:拿干净的数据回答业务问题、搭仪表盘、找洞察。这是分析。
- 分析工程师:中间缺失的那一环。他们把落进仓库的原始、杂乱数据,转换成干净、可信、定义清晰的数据集,让分析师能真正依赖。
一句话版本:数据分析师的时间花在分析数据上;分析工程师的时间花在转换、测试和记录数据上——这样当分析师问起"收入"时,只有一个定义,它是对的,所有人用的都是它。
让分析工程成为一门学科而不只是一个岗位头衔的,是它背后的核心主张:把软件工程实践带进数据。版本控制、测试、文档、模块化、代码评审。正是数据转换从来没有过的那些习惯。
dbt:把工程纪律带进数据的那个工具
dbt(data build tool)是一个开源框架,如今已经成为分析工程的骨架。它做的事听起来平淡无奇,直到你意识到此前根本没人这么做:它让你把数据转换写成模块化、受版本控制、带测试、有文档的SQL。
落到实践里是这样,每一块都对应着两个仪表盘那个问题:
转换变成Git里的代码。不再是一个藏在BI工具里的查询,你的"收入"定义是一个SQL文件,放在受版本控制的仓库里。每次改动都被追踪、被评审、可归因。只有一个文件定义收入,你能看到它的完整历史。定义散落的问题消失了,因为定义现在只住在一个地方。
你可以对数据写测试。这是开发者一旦看懂就会喜欢上的部分。dbt让你写下断言,持续运行——比如收入不该为负,比如每个订单应该恰好对应一个客户。数据出问题时,你在它流向下游之前就知道。
定义只写一次,处处复用。下游的仪表盘、报表、模型都引用同一个定义,而不是各自重写一遍。两个仪表盘给出两个答案的空间,从结构上被堵死了。
文档跟着代码走。假设不再留在某个人脑子里,而是写在定义旁边,谁都能查。
回到开头那个会议室。两个仪表盘对不上,从来不是某个人算错了,而是"收入"这个词在公司里从来没有过一个被写下、被测试、被共享的定义。分析工程和dbt做的,就是把这件事从"每个人各自理解"变成"一个文件说了算"。
热门跟贴