简介:这份文档面向 BI 项目中的数据仓库建设者、ETL 开发人员与数据工程初学者,系统讲解 ETL 设计中数据抽取、清洗转换与加载三个环节的落地思路,帮助读者理清从业务系统到 ODS、再到 DW 的完整链路。资源包共 1 个 docx 文件,约 20KB,内容围绕数据源调研问题、同构与异构数据源的抽取方式、增量更新判断、脏数据分类处理、不一致数据与粒度转换、商务规则计算,以及 ETL 日志分级与警告发送等模块展开,并对比 ETL 工具、纯 SQL 及两者结合三种实现路径的优劣。已有 1535 人学习,适合需要快速建立 ETL 设计框架、对照检查抽取与清洗方案是否完备的读者参考。
1. 数据搬运工的秘密:ETL 到底是个什么东西
你有没有遇到过这种场面:老板甩过来一句“把几个业务系统的数据合到一起,做个销售看板”,你打开电脑一看,订单系统一套表、客户系统另一套表、财务那边还躺着一堆 Excel,字段名对不上,日期格式五花八门,同一个客户在三个系统里居然有三个编号。这时候老手嘴里往往会蹦出一个词——ETL。它不是什么新潮框架,也不是某个具体软件,而是一套“把数据从源头搬到能用地方”的固定动作。说白了,ETL 就是数据世界里的搬家队:先从各个旧房子里把东西搬出来(抽取),路上该修的修、该扔的扔、该重新打包的重新打包(清洗转换),最后整整齐齐码进新仓库(加载)。搞懂它,你就明白为什么很多数据项目一半时间都耗在“搬”上,也就能听懂那些做 BI 的人为什么天天喊累。
2. 抽取为什么最考验调研:数据源决定了搬法
2.1 抽取之前先问四个问题
数据抽取听起来就是写个查询把数据拉过来,但真正动手之前,调研阶段的信息收集才是决定后面顺不顺的关键。原文里列得很清楚:数据从几个业务系统来、各系统跑的是什么数据库、有没有手工数据且量多大、有没有非结构化数据。这四个问题看着朴素,实际每一条都对应一种搬法。比如你以为是三个系统,结果一查发现还有两个部门在用 Excel 手工记账,那抽取方案就得临时加一条文件导入的通道;再比如某个系统跑的是和数仓完全不同的数据库,链接方式就得换。打个比方,这就像搬家前先清点:有几户人家、每户住几楼、有没有大件家具要拆、有没有易碎品要单独包。清点没做,搬到一半发现钢琴进不了电梯,只能返工。所以抽取设计的第一步不是写代码,而是把数据源摸清楚,把“从哪来、怎么连、量多大”这三件事落到纸面上。
2.2 同构数据源:直接建链接最省事
如果业务系统和数据仓库用的是同一类数据库,事情就简单很多。这类数据库通常自带数据库链接功能,可以在数仓服务器和业务系统之间建立一条直接的访问通道,然后写一条查询语句就能把数据取过来。这种方式的优点是链路短、延迟低,不用额外导文件,也不用中间转存。但要注意,直接链接意味着抽取任务会实时打到业务库上,如果业务系统本身负载就高,抽取时间又选在白天,很容易把人家拖慢。血泪经验是:能建链接不等于可以随便建,抽取窗口尽量避开业务高峰,大批量拉数时加个限流或者分批取,别让搬家队把老房子的门框给挤坏了。另外,链接建好之后权限要收窄,只给读权限,别让抽取账号顺手能改数据,那是给自己埋雷。
2.3 异构数据源:ODBC、文件、接口三条路
业务系统和数仓不是同一类数据库时,情况就复杂一些。常见做法是通过 ODBC 这类通用连接方式建立通道,让两边能对话。如果连通道都建不起来,原文给了两条备选:一条是用工具把源数据导出成文本或表格文件,再导入到 ODS 里;另一条是通过程序接口来完成。文件这条路适合数据量不大、更新频率不高的场景,比如某些手工维护的台账;接口这条路适合源系统有开放能力、但不愿意让你直连数据库的情况。这里有个容易翻车的点:导出文件时编码和分隔符不统一,导进来全是乱码或者整行挤在一列里。所以文件通道一定要在导入前做格式校验,字段数对不对、编码是不是统一、有没有多余的空行,这些检查写进流程里,比事后排查省事得多。
2.4 增量抽取:时间戳是最好用的路标
数据量一大,每次全量拉一遍就不现实了,必须考虑增量抽取。原文给的办法很实在:业务系统一般会记录业务发生的时间,拿这个时间当增量标志,每次抽取前先看 ODS 里已有的最大时间,然后去业务系统取大于这个时间的所有记录。这就像搬家时只搬新添置的东西,旧家具已经在仓库里了,不用再搬一遍。但这条路有个前提——业务系统得有时间戳,而现实中不少老系统恰恰没有,或者只有部分表有。遇到没有时间戳的系统,就得退而求其次,用自增主键、或者对比全量做差异识别,代价是效率低一些。所以增量方案设计时,先确认源表有没有可靠的时间字段,有就优先用,没有就提前想好替代方案,别等到上线才发现增量根本跑不起来。
3. 清洗与转换为什么最耗时间:脏数据的三张面孔
3.1 不完整的数据:缺了就得补,补之前先确认
清洗环节碰到的第一类问题是不完整的数据,特征是本该有的信息缺失,比如供应商名称空着、分公司名称没填、客户的区域信息缺失,或者主表和明细表对不上号。这类数据不能直接扔进数仓,因为缺了关键字段,后面的分析口径就乱了。原文的处理办法是把这类数据过滤出来,按缺失内容分别写成不同的表格文件提交给业务方,要求在规定时间内补全,补全之后才写入数据仓库。这里的关键动作是“分类提交”,而不是一股脑丢一个几万行的清单过去,业务方看到就头大。按缺失字段拆开、按责任部门拆开,补起来才有抓手。另外要留个心眼:有些字段看着缺失,其实是业务上本来就不要求填,这种要先和业务确认清楚,别把正常数据当成脏数据反复退回,来回折腾几轮,业务方就不配合了。
3.2 错误的数据:分两类对待,一类能修一类会炸
错误数据的来源通常是业务系统在录入时没做校验,直接写进了库。原文举的例子很典型:数值里混进全角数字字符、字符串后面带了个回车、日期格式不对、日期越界。这些错误要分两类看。像全角字符、前后有不可见字符这类问题,可以用 SQL 找出来,要求业务方在源系统修正之后再抽取;而日期格式不正确或者日期越界这类错误,会直接导致 ETL 运行失败,属于必须优先处理的硬伤,得去源库用 SQL 挑出来,交给业务主管部门限期修正。打个比方,前者像衣服上沾了灰,拍一拍还能穿;后者像扣子扣错了眼,不重新扣整件衣服就是歪的。处理顺序上,先解决会让任务崩掉的硬错误,再处理影响观感的软错误,否则任务天天挂,后面的清洗根本推进不下去。
3.3 重复的数据:维表重灾区,确认权交给业务
重复数据在维表里特别常见,比如同一个供应商在两张表里出现两次、同一个客户因为录入方式不同产生了两条记录。原文的做法是把重复记录的所有字段导出来,让业务方确认并整理。这里有个原则值得记住:去重不是技术人员拍脑袋决定的,哪条留哪条删,涉及业务含义,必须由业务方确认。技术人员能做的是把重复识别规则写清楚,比如按编码判重还是按名称加证件号判重,规则不同结果可能差很多。另外,清洗是一个反复的过程,不可能几天内完成,原文说得很直白——只有不断发现问题、解决问题。所以清洗规则要可配置、可回溯,今天加一条规则过滤掉一批数据,明天业务说这批其实有用,你得能快速把规则撤回来重新跑,而不是从头再来一遍。
3.4 转换的三件事:统一口径、调整粒度、算好指标
清洗之后是转换,原文把它归纳为三类任务。第一类是不一致数据的转换,本质是整合:同一个供应商在结算系统里编码是某一种格式,在客户系统里又是另一种格式,抽过来之后要统一成一个编码,否则分析时同一个对象被算成两个。第二类是数据粒度的转换,业务系统存的是非常明细的数据,而数据仓库是拿来分析的,不需要细到每一笔,通常会按数仓的粒度做聚合。第三类是商务规则的计算,不同企业有不同指标,有些指标不是简单加减能出来的,需要在 ETL 里算好再存进数仓,供分析直接使用。这三件事里,第一件最容易埋隐患,因为编码映射关系往往散落在各个业务方手里,建议单独维护一张映射表,改一处全局生效,别把映射逻辑硬编码在几十个脚本里,后期维护会让人崩溃。
4. 加载与日志:别让搬完的数据变成黑匣子
4.1 加载不是终点,写进去只是开始
数据清洗转换完之后,通常直接写入数据仓库,这一步就是加载。听起来简单,但加载方式的选择会影响后续的可维护性。全量覆盖适合数据量小、变化频繁的维表;增量追加适合流水类的事实表;还有先删后插的方式,适合需要保证某一天数据完整重跑的场景。选哪种,取决于这张表下游怎么用、重跑频率高不高。容易被忽略的是加载失败的兜底:写到一半断了怎么办?是整批回滚还是标记断点续传?这些在設計时就要定好,否则一次失败就得人工清表重来,数据量大的时候光清理就要半天。加载完成之后最好再做一次行数和关键字段的非空校验,确认搬过来的东西是完整的,而不是搬了一半就宣布完工。
4.2 三类日志:过程、错误、总体各管一段
ETL 跑起来之后,你得随时知道它跑到哪了、有没有出错、错在哪。原文把日志分成三类:执行过程日志记录每一步的起始时间、影响行数,是流水账形式;错误日志在某个模块出错时记录出错时间、出错模块和错误信息;总体日志只记开始时间、结束时间和是否成功。这三类日志各有各的用处:过程日志用来定位慢在哪一步,错误日志用来快速找到故障点,总体日志用来做运行状态的汇总看板。打个比方,过程日志是行车记录仪,错误日志是故障码,总体日志是仪表盘上的那盏发动机灯。三者缺一不可,只记总体日志,出错了你不知道哪一步炸的;只记过程日志,信息太多反而找不到重点。建议在开发初期就把日志表结构定好,别等到出了问题才临时加字段。
4.3 警告发送:出错要让人知道,别等业务来问
光写日志还不够,ETL 出错了得主动通知系统管理员。原文提到常用方式是给管理员发邮件,并附上出错信息,方便排查。这一点在实际项目里经常被轻视,觉得日志写了就行,结果任务半夜挂了,第二天业务方来看报表发现数据没更新,才反过来问技术,一来一回半天就过去了。警告发送的关键是“及时”和“可操作”:邮件里要带任务名、出错时间、错误摘要,最好再带上日志表的查询入口,让收到的人一眼知道去哪看详情。另外要控制噪音,同一个错误连续触发时做一下合并,别一晚上发几百封邮件,最后管理员直接把规则屏蔽了,真出大事反而没人看。这属于典型的后悔药,前期花半小时配好,后期省下的是无数个被叫醒的夜晚。
5. 工具还是手写 SQL:选错路线的代价与边界
5.1 三种实现路线各自的脾气
ETL 的实现常见三条路:借助 ETL 工具、纯 SQL 方式、工具和 SQL 结合。工具路线的优点是能快速搭起工程,把复杂的编码任务屏蔽掉,速度上来了、难度降下去了,但灵活性欠缺,遇到特殊逻辑往往要绕路。纯 SQL 路线反过来,灵活、能针对性地优化运行效率,但编码复杂,对写的人技术要求高,维护成本也高。第三条路是两者结合,用工具管调度和流程,用 SQL 处理复杂转换,综合了前两者的优点,能明显提高开发速度和效率。这三条路没有绝对的好坏,只有合不合适。打个比方,工具像成品家具,搬回家就能用,但尺寸不一定贴合你家墙角;SQL 像请木工现场打,严丝合缝但费工费时;结合路线是成品加局部定制,多数家庭装修最后都走这条。
5.2 常见误区:这几个概念最容易搅在一起
第一个易混点是 ETL 和 BI 的关系。很多人以为 ETL 就是 BI,其实 ETL 是 BI 项目里负责数据准备的那一段,BI 还包括报表、分析、展现。混淆的原因是两个词经常一起出现,区分方法是看职责:ETL 管“把数据弄干净弄到位”,BI 管“把数据用起来看明白”。
第二个易混点是 ODS 和数据仓库。两者都是存数据的地方,但 ODS 更贴近源系统,存放的是抽取过来、做了初步清洗的原始粒度数据;数据仓库则是经过转换、按分析粒度组织好的数据。混淆的原因是都叫“库”,区分方法是看数据形态:ODS 里的数据还带着业务系统的影子,数仓里的数据已经按分析需求重新组织过。
第三个易混点是数据清洗和数据转换。清洗侧重“去坏留好”,处理的是不完整、错误、重复的数据;转换侧重“统一和加工”,处理的是编码不一致、粒度调整、指标计算。两者经常在同一个流程里交替出现,所以容易被当成一件事,区分方法是看动作目的:清洗是修毛病,转换是改形态。
第四个易混点是增量抽取和全量抽取的适用边界。有人觉得增量一定比全量高级,其实不然。数据量小、变化频繁、需要保证一致性的场景,全量覆盖反而更稳;数据量大、源表有时间戳的场景,增量才划算。混淆的原因是“增量”听起来更专业,区分方法是看数据量和源表条件,别为了用增量而用增量。
第五个易混点是日志和警告。日志是写下来给自己查的,警告是发出去让别人知道的。只写日志不发警告,出了问题没人及时处理;只发警告不写日志,收到警告也不知道去哪查细节。两者是配套的,不是二选一。
5.3 什么时候用、什么时候别用
ETL 这套方法适合什么场景?当你有多个数据源需要合并、源数据质量参差不齐、下游要做分析而不是做交易、并且数据需要定期更新时,ETL 就是绕不开的一环。反过来,如果只是单库单表做个简单查询、数据本身就干净、也不需要历史留存,那硬上一套 ETL 流程就是杀鸡用牛刀,维护成本比收益还高。还有一种情况要谨慎:源系统本身极不稳定、字段说改就改,这时候与其急着建复杂的转换逻辑,不如先把源头的规范推动一下,否则 ETL 天天跟着改,改到最后没人敢动。
我自己的习惯是,每接一个数据整合的活,先花半天把源系统清单、字段质量、更新频率这三样摸一遍,再决定抽取方式和清洗规则,宁可前期慢一点,也不要在上线后被脏数据反复打脸。从那以后我每次设计 ETL 都强制走一遍“先调研再动手”的流程,翻车的次数明显少了。希望这些内容能帮到你,这份资料里对抽取、清洗、转换、日志的拆解更细,需要的时候可以拿去对照着看。
本文还有配套的精品资源,点击获取