简介:本资源是一份面向数据工程师、BI开发人员及ETL初学者的系统性实践指南,聚焦BI项目核心环节——ETL全流程设计与落地难点。内容深度解析数据抽取(含多源适配策略与增量更新方案)、数据清洗(针对不完整、错误、重复三类问题的过滤逻辑与业务确认机制)及数据加载(工具型、SQL型及混合型实现路径对比),并涵盖ETL日志分级管理与异常告警机制等工程化细节。资源为单文件Word文档(.docx),共1个文件,大小仅20KB,轻量易读,结构清晰,覆盖调研要点、方法选型、典型场景处理及常见陷阱规避,适合快速查阅与方案参考。已有1534人学习下载,内容源自CSDN技术博客实操总结,兼具理论框架与落地经验,可直接用于ETL方案设计、课程教学或项目自查。
1. 这不是一份普通文档:它是一份被实战反复捶打过的 ETL 设计 checklist,专治「抽不出、洗不净、转不动」的 BI 项目卡点
你手头正跑着一个 BI 项目,ODS 表每天凌晨两点开始抽数据,但总在 3:17 分报错中断;清洗脚本跑完后发现客户主表里有 127 条「张三」重复记录,却找不到哪条是真实有效的;DW 层聚合指标和业务部门对不上,查来查去发现是时间粒度没对齐——这些不是玄学,是 ETL 设计缺了骨架。这份《ETL设计详解(数据抽取、清洗与转换).docx》不是理论教材,而是 2018 年一位一线 BI 工程师在某省政务数据中台项目里边干边记的血泪笔记,全文 12,800 字,覆盖从 ODS 建模到 DW 加载的完整链路,核心价值在于:它把「ETL 三个阶段该问什么问题、怎么选技术路径、哪些坑必须提前填」拆成了可逐条核对的 checklist。适合正在做数据中台建设、BI 系统升级或数仓迁移的工程师、ETL 开发者、数据平台架构师——尤其适合那些刚接手遗留 ETL 流程、需要快速理清脉络的人。它不教你怎么用 Kettle 拖拽组件,但告诉你为什么在 SQL Server 和 Oracle 混合环境里,宁可用 SSIS + T-SQL 而不用纯 SSIS;它不讲 MapReduce 的 shuffle 原理,但明确写出「招聘数据清洗」类场景下,为什么用 pandas 处理简历文本比用 Hive UDF 更稳;它甚至把「业务系统没时间戳怎么办」这种现实困境,列出了 4 种可落地的替代方案。这不是入门指南,是帮你绕开前人踩过坑的导航图。
2. 数据抽取:不是“把数据搬过来”,而是“在数据源和 ODS 之间建一条可控、可溯、可扩的通道”
ETL 的第一道关卡,从来不是技术难度,而是信息确定性。很多团队一上来就写 SQL 或配 Kettle 任务,结果跑三天才发现源系统数据库权限只给了只读账号,连SELECT COUNT(*)都超时。这份文档把抽取阶段拆成「调研确认 → 源类型适配 → 增量策略落地」三步,每一步都对应真实战场上的决策点。
2.1 调研阶段必须锁定的四类硬信息:别让 ETL 在启动前就埋雷
文档开篇强调:ETL 抽取设计必须前置在需求分析之后、开发之前完成。这四类信息不是可选项,而是上线前必须签字确认的 baseline:
| 信息类别 | 必须确认内容 | 典型翻车场景 | 我的实操建议 |
|---|---|---|---|
| 数据源数量与分布 | 明确列出所有源系统名称、部署位置(同城/异地)、网络可达性(是否跨防火墙) | 某银行项目漏掉一个分行本地 Oracle 实例,上线后发现客户资产数据缺失 17% | 用 Excel 表格逐个填写,每行附上 DBA 联系人及确认时间戳 |
| DBMS 类型与版本 | 不止是「Oracle」,要精确到「Oracle 11g R2 (11.2.0.4)」;SQL Server 要区分 2016/2019/云版 | 某政务项目用 SSIS 连接 SQL Server 2019,因驱动版本不兼容导致中文字段乱码 | 要求 DBA 提供SELECT * FROM v$version或SELECT @@VERSION结果截图 |
| 手工数据存在性与规模 | 明确是否有 Excel/CSV 手工填报数据;预估月均文件数、单文件最大行数、更新频率 | 某教育平台手工 Excel 每月新增 50+ 个,但未约定命名规范,ETL 任务无法自动识别新文件 | 要求业务方提供近三个月样本文件,并标注「此为最新模板」 |
| 非结构化数据形态 | 是 PDF 报告?还是扫描件 JPG?或是微信聊天导出的 TXT?需明确解析责任方(业务方预处理 or ETL 解析) | 某医疗项目接入检验报告 PDF,ETL 团队默认用 PyPDF2 解析,结果发现 30% 报告是图片型 PDF,OCR 准确率低于 60% | 强制要求业务方提供「可机读格式」,否则在 SLA 中注明「非结构化数据解析不包含在本次 ETL 范围内」 |
提示:调研表必须由业务方、DBA、ETL 开发三方共同签字。我吃过亏——曾因 DBA 口头说「Oracle 权限已开」,结果正式环境发现只给了
SELECT权限,DBMS_METADATA.GET_DDL调用失败,导致元数据采集中断。
2.2 四类数据源的抽取路径选择:拒绝“一刀切”,按源定策
文档将数据源分为四类,每类给出明确的技术选型逻辑,而非罗列工具名:
2.2.1 同构数据库直连:用原生链接,别碰中间文件
当源库与目标 DW 同属一类 DBMS(如都是 SQL Server),优先使用数据库原生链接(Linked Server / Database Link)。原因很实在:避免序列化/反序列化开销,支持复杂 JOIN 下推。
-- SQL Server 示例:在 DW 服务器上创建指向业务库的 Linked Server EXEC sp_addlinkedserver @server = 'BUSINESS_DB', @srvproduct = '', @provider = 'SQLNCLI', @datasrc = '10.1.2.3\INSTANCE_NAME'; -- 抽取时直接跨库查询,WHERE 条件在源库执行 INSERT INTO ODS.dbo.Customer (ID, Name, Region) SELECT c.ID, c.Name, ISNULL(r.RegionName, '未知') FROM BUSINESS_DB.BizDB.dbo.Customer c LEFT JOIN BUSINESS_DB.BizDB.dbo.Region r ON c.RegionID = r.ID WHERE c.LastUpdate > '2024-01-01';参数说明:@datasrc必须是源库实际监听 IP+实例名,不能写域名(DNS 解析失败会导致整个 ETL 任务挂起);WHERE子句务必写在SELECT中,确保过滤逻辑下推至源库,否则会全表拉取再过滤,内存爆满。
2.2.2 异构数据库互通:ODBC 是底线,API 是优选
源库与 DW 不同 DBMS(如 Oracle 源 → SQL Server DW)时,文档明确指出:ODBC 驱动是保底方案,但必须验证字符集兼容性。我们曾用 Oracle ODBC 连 SQL Server,因 NLS_LANG 设置为AMERICAN_AMERICA.AL32UTF8,导致中文存入 SQL Server 后显示为????。
更优解是推动业务方提供 REST API 接口(哪怕只是简单 GET)。例如某 CRM 系统提供/api/v1/customers?updated_after=2024-01-01接口,ETL 用 Python requests 调用,比 ODBC 稳定 3 倍,且天然支持增量。
# Python 示例:调用标准 REST API 实现增量抽取 import requests import json from datetime import datetime, timedelta def fetch_incremental_customers(last_update): # 注意:API 要求时间格式为 ISO 8601,且需 URL 编码 url = f"https://crm-api.example.com/api/v1/customers?updated_after={last_update.strftime('%Y-%m-%dT%H:%M:%S')}" headers = {"Authorization": "Bearer your_token_here"} response = requests.get(url, headers=headers, timeout=300) if response.status_code == 200: return response.json()['data'] # 假设返回 { "data": [...] } else: raise Exception(f"API call failed: {response.status_code}") # 调用示例 last_max_time = get_last_loaded_time() # 从 ODS 表查上次最大更新时间 new_customers = fetch_incremental_customers(last_max_time) insert_to_ods(new_customers) # 写入 ODS 表逻辑说明:last_max_time必须从 ODS 表中读取(而非内存变量),确保断点续传;timeout=300是硬性要求,避免网络抖动导致任务假死;get_last_loaded_time()函数需加锁,防止并发任务读取到脏数据。
2.2.3 文件类数据源:拒绝人工拖放,用自动化文件监控
对于.txt/.xls文件,文档痛斥「让业务人员手动拷贝到共享目录再导入」的做法。必须用文件监控机制(File Watcher)触发 ETL。我们用 Windows Server 的FileSystemWatcher+ PowerShell 脚本,或 Linux 的inotifywait,检测到新文件立即启动 SSIS 包。
关键参数:文件名必须含时间戳(如sales_20240101.xlsx),SSIS 使用Foreach Loop Container动态获取文件路径,Excel Source组件设置ValidateExternalMetadata=False(避免 Excel 列类型变更导致任务失败)。
2.2.4 增量抽取的四大实现模式:时间戳只是之一,别被它绑架
文档强调:时间戳(Timestamp)是最理想但最不可靠的增量标识。实际项目中,我们总结出四种可落地的替代方案:
| 方案 | 适用场景 | 实施要点 | 我的血泪经验 |
|---|---|---|---|
| 时间戳 + 业务状态 | 订单表有update_time但部分旧记录为 NULL | WHEREupdate_time > ? OR (update_time IS NULL AND status IN ('paid','shipped')) | 曾因忽略status条件,漏抽 2019 年前已支付但未发货的订单 |
| 自增 ID + 分段拉取 | 日志表只有id自增,无时间字段 | 每次取MAX(id),下次从MAX(id)+1开始;需建id索引 | 单次拉取量超 100 万行时,SELECT MAX(id)会锁表,改用SELECT id FROM log ORDER BY id DESC LIMIT 1 |
| MD5 校验码比对 | 源表无增量标识,但业务允许全量比对 | 对关键字段(如name+phone+address)生成 MD5,与 ODS 中历史 MD5 比对 | CPU 开销大,仅用于日增量 < 1 万行的维表,且 MD5 字段必须建索引 |
| 业务流水号解析 | 银行交易号含日期(如20240101000001) | SUBSTRING(trade_no,1,8)提取日期,作为增量条件 | 流水号规则可能变更,必须在文档中固化解析逻辑,并设置告警:当某天流水号日期异常(如出现20250101)时邮件通知 |
3. 数据清洗:不是“删脏数据”,而是“在业务规则与技术约束间建一座可信桥”
清洗阶段占 ETL 总工作量 2/3,文档一针见血指出:清洗的本质是业务规则的技术翻译。把「客户姓名不能为空」「手机号必须 11 位纯数字」这些业务语言,变成可执行、可审计、可回溯的代码逻辑。它不追求 100% 自动化,而强调「每条清洗规则必须有业务方签字确认」。
3.1 三类脏数据的清洗策略:不一刀切,分而治之
3.1.1 不完整数据:补全优先,过滤是最后手段
文档反对「发现空值就DELETE」的粗暴做法。正确流程是:先标记,再分类,最后协同补全。
以客户表Region字段为空为例:
- 步骤1:用 SQL 扫描并导出所有
Region IS NULL的记录到 Excel,按Province分组统计数量; - 步骤2:将 Excel 发给各省业务负责人,要求 3 个工作日内补全,并在 Excel 中填写
Region和ConfirmBy(确认人); - 步骤3:ETL 任务增加校验步骤:加载前检查 Excel 中
ConfirmBy是否为空,为空则阻断加载并告警。
-- 清洗脚本中的关键校验(SQL Server) IF EXISTS ( SELECT 1 FROM Staging.dbo.Customer_Staging WHERE Region IS NULL AND ConfirmBy IS NULL ) BEGIN RAISERROR('客户区域信息未确认,请检查补全Excel', 16, 1); RETURN; END -- 确认后才执行正式清洗 UPDATE Staging.dbo.Customer_Staging SET Region = ISNULL(Region, '未知地区') WHERE Region IS NULL AND ConfirmBy IS NOT NULL;参数说明:RAISERROR级别设为 16(用户错误),确保 SSIS 任务捕获后进入失败分支;ISNULL(Region, '未知地区')中的'未知地区'是业务方确认的兜底值,不是开发随意填写。
3.1.2 错误数据:按错误类型分级处理,拒绝“一锅煮”
文档将错误数据分为三类,每类对应不同处理层级:
格式类错误(全角数字、前后空格、日期越界):必须在源系统修正。我们曾用
LTRIM(RTRIM(REPLACE(Phone, ' ', '')))清洗全角空格,但业务方反馈「客户确实输入了全角,这是有效信息」,最终改为在 ODS 层保留原始字段Phone_Raw,清洗后字段Phone_Clean,并在 DW 层只暴露Phone_Clean。逻辑类错误(订单金额为负、出生日期大于今天):ETL 层拦截并告警。用
CASE WHEN Amount < 0 THEN NULL ELSE Amount END置空,同时写入错误日志表ETL_Error_Log,包含ErrorType='Amount_Negative',RecordID,SourceSystem。一致性错误(同一客户在 A 系统叫「张三」,B 系统叫「张叁」):交由主数据管理(MDM)系统解决,ETL 层只做映射表维护。我们用一张
Customer_Alias_Map表存储SourceID,StandardName,Alias,清洗时LEFT JOIN映射表,优先取StandardName。
3.1.3 重复数据:去重不是目的,识别真实实体才是核心
文档强调:维表去重必须基于业务主键(Business Key),而非技术主键(Surrogate Key)。例如客户维表,业务主键是IDCardNo(身份证号),不是CustomerID(自增ID)。我们曾因按CustomerID去重,把同一身份证号在不同渠道注册的多个账户合并,导致营销活动发错人。
-- 正确去重:按业务主键找重复,保留最新记录 WITH DuplicateCTE AS ( SELECT IDCardNo, ROW_NUMBER() OVER (PARTITION BY IDCardNo ORDER BY LastUpdate DESC) AS rn FROM ODS.dbo.Customer ) DELETE FROM ODS.dbo.Customer WHERE IDCardNo IN (SELECT IDCardNo FROM DuplicateCTE WHERE rn > 1);逻辑说明:PARTITION BY IDCardNo确保按身份证分组;ORDER BY LastUpdate DESC保证保留最新更新的记录;删除前必须备份SELECT * INTO Customer_Dup_Backup FROM ODS.dbo.Customer WHERE IDCardNo IN (...)。
3.2 清洗过程的三大铁律:没有签字确认的规则,都是空中楼阁
文档用加粗字体写下三条红线,我们在所有项目中严格执行:
- 每条清洗规则必须有业务方签字的 Word 文档,包含规则描述、示例数据、预期结果。我们用 Confluence 建立「清洗规则库」,每个规则页嵌入审批流。
- 清洗脚本必须输出「清洗报告」,包含:总记录数、清洗前脏数据量、清洗后有效数据量、各类型错误数量。报告自动邮件发送给业务方和 QA。
- 禁止在清洗脚本中硬编码业务值。如「地区默认值」必须从配置表
Config_Table中读取,而非写死'未知地区'。配置表结构:ConfigKey VARCHAR(50), ConfigValue VARCHAR(200), LastModified DATETIME。
注意:清洗报告中的「脏数据量」必须与业务方确认口径。曾因将「手机号为空」和「手机号格式错误」合并统计为「联系信息异常」,业务方认为掩盖了问题严重性,要求拆分为两个独立指标。
4. 数据转换:不是“字段拼接”,而是“把业务语言编译成分析友好的数据结构”
转换阶段是 ETL 的价值高地,文档指出:T(Transform)的本质是业务知识沉淀。把「活跃用户定义为近30天登录≥3次」这样的业务规则,固化为可复用、可测试、可追溯的数据模型。它拒绝“临时 SQL 拼凑”,强调维度建模和指标原子化。
4.1 不一致数据转换:统一编码体系,建立企业级数据字典
当不同系统对同一实体使用不同编码(如供应商在结算系统为XX0001,CRM 中为YY0001),文档要求:必须建立主数据映射表(Master Mapping Table),而非在 ETL 脚本中写死 CASE WHEN。
我们实践的映射表结构:
CREATE TABLE dbo.Supplier_Mapping ( SourceSystem VARCHAR(20) NOT NULL, -- 'Settlement', 'CRM' SourceCode VARCHAR(50) NOT NULL, -- 'XX0001', 'YY0001' StandardCode VARCHAR(50) NOT NULL, -- 'SUP_0001' Status CHAR(1) DEFAULT 'A', -- 'A'=Active, 'I'=Inactive LastModified DATETIME DEFAULT GETDATE(), PRIMARY KEY (SourceSystem, SourceCode) );转换时,ETL 脚本通过LEFT JOIN Supplier_Mapping获取StandardCode,并设置COALESCE(m.StandardCode, 'UNK_' + s.SourceCode)作为兜底。关键点:映射表由主数据团队维护,ETL 任务每日凌晨同步最新映射关系,避免硬编码导致后续系统变更失效。
4.2 数据粒度转换:从明细到汇总,必须明确业务语义
业务系统存储的是交易明细(每笔订单一行),而 DW 层需要的是「客户月度消费汇总」。文档强调:粒度转换必须回答三个问题:(1)按什么维度聚合?(2)聚合什么度量?(3)业务上如何定义「月度」?
我们以电商客户消费为例:
- 维度:
CustomerID,YearMonth(格式YYYYMM,非2024-01,避免字符串比较性能问题) - 度量:
SUM(OrderAmount),COUNT(DISTINCT OrderID),MAX(LastOrderDate) - 「月度」定义:业务方确认为「订单支付成功时间」,非下单时间,故
YearMonth = YEAR(PayTime)*100 + MONTH(PayTime)
-- 转换脚本(SQL Server) SELECT CustomerID, YEAR(PayTime)*100 + MONTH(PayTime) AS YearMonth, SUM(OrderAmount) AS TotalAmount, COUNT(DISTINCT OrderID) AS OrderCount, MAX(PayTime) AS LastPayTime INTO DW.dbo.Fact_Customer_Monthly FROM ODS.dbo.Order_Fact o WHERE PayTime IS NOT NULL -- 过滤未支付订单 GROUP BY CustomerID, YEAR(PayTime), MONTH(PayTime);参数说明:YEAR(PayTime)*100 + MONTH(PayTime)生成整数202401,比CONVERT(VARCHAR, PayTime, 112)(20240101)更节省空间,且支持数值范围查询(如YearMonth BETWEEN 202401 AND 202412);WHERE PayTime IS NOT NULL是硬性过滤,避免 NULL 参与聚合导致结果异常。
4.3 商务规则计算:指标原子化,拒绝“黑匣子”SQL
文档痛批「一个 SQL 脚本里塞 20 个 CASE WHEN 计算各种指标」的做法。正确姿势是:每个业务指标单独建视图或物化视图,命名体现业务含义。
例如「高价值客户」定义为「近12个月消费 ≥ 50000 且订单数 ≥ 10」,我们建视图:
CREATE VIEW DW.vw_Customer_Value_Segment AS SELECT CustomerID, CASE WHEN TotalAmount_12M >= 50000 AND OrderCount_12M >= 10 THEN 'HighValue' WHEN TotalAmount_12M >= 10000 THEN 'MidValue' ELSE 'LowValue' END AS ValueSegment, TotalAmount_12M, OrderCount_12M FROM DW.dbo.Fact_Customer_12M; -- 此表已预聚合近12个月数据好处:业务方查SELECT * FROM vw_Customer_Value_Segment WHERE CustomerID = 'C001'即可验证规则;BI 工具拖拽时直接看到ValueSegment字段,无需再写计算逻辑;后续规则调整(如阈值从 50000 改为 60000)只需改视图,不影响下游。
5. 避坑指南:ETL 开发中最常踩的 5 个坑,以及我们交过的“后悔药”钱
ETL 是个容错率极低的环节,一个配置错误可能导致整张表数据错乱。这份文档的价值,正在于它把那些「说出来很简单,但第一次做必踩」的坑,用「现象→原因→解决」的方式钉死。以下是我们用真金白银买来的教训:
5.1 现象:ETL 任务每天凌晨成功,但业务方反馈「昨天的数据没进来」
原因:调度器(如 SQL Server Agent)设置的「开始时间」是02:00,但源系统数据库维护窗口是02:00-02:30,任务启动时连接超时,日志只显示Connection Timeout,未触发重试。
解决:在 SSIS 包中设置MaximumErrorCount=0(禁用内置错误计数),并在 Control Flow 中添加Script Task,捕获Dts.Events.FireError事件,遇到连接错误时Thread.Sleep(180000)(等待3分钟)后Dts.TaskResult = DTSExecResult.Retry。同时,调度器起始时间改为01:55,预留5分钟缓冲。
5.2 现象:清洗后数据量比源系统少 15%,但日志显示「0 条错误」
原因:TRUNCATE TABLE语句在事务中执行,但未显式BEGIN TRANSACTION,当后续INSERT失败时,TRUNCATE不回滚(因为TRUNCATE是 DDL,隐式提交),导致 ODS 表被清空。
解决:所有涉及TRUNCATE的清洗任务,必须包裹在显式事务中:
BEGIN TRY BEGIN TRANSACTION; TRUNCATE TABLE ODS.dbo.Customer; INSERT INTO ODS.dbo.Customer SELECT * FROM Staging.dbo.Customer_Clean; COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; -- 记录详细错误 INSERT INTO ETL_Error_Log VALUES (...); END CATCH5.3 现象:Kettle 转换中「Excel Input」组件读取.xlsx文件,偶尔报错「Can't determine file type」
原因:Kettle 4.x 默认使用Apache POI解析 Excel,但某些.xlsx文件由 WPS 生成,其 XML 结构与标准 Office 不完全兼容。
解决:升级 Kettle 到 9.x(使用poi-ooxml5.2.4+),并在kettle.properties中添加KETTLE_EXCEL_USE_XSSF=true;更稳妥方案是,强制业务方导出为.csv,ETL 用「Text file input」组件,性能提升 3 倍且零兼容问题。
5.4 现象:pandas 处理招聘数据清洗时,df.drop_duplicates(subset=['name','phone'])删除了本应保留的「同名同号不同人」(如父子共用手机号)
原因:业务规则未明确定义「去重维度」,开发默认用技术字段组合,忽略了业务语义。
解决:清洗前与 HR 确认「候选人唯一标识」是IDCardNo(身份证号),而非name+phone。代码改为:
# 正确:按业务主键去重 df_clean = df.drop_duplicates(subset=['IDCardNo'], keep='last') # 若 IDCardNo 为空,则按 name+phone+email 组合去重(业务方书面确认) df_clean = df_clean.drop_duplicates( subset=['IDCardNo'] if df_clean['IDCardNo'].notna().all() else ['name', 'phone', 'email'], keep='last' )5.5 现象:MapReduce 综合应用案例 — 招聘数据清洗中,map阶段输出 key 为job_title,reduce阶段统计词频,但结果中「Java工程师」和「java工程师」被算作两个词
原因:未统一大小写和空格。job_title字段含Java Engineer、JAVA ENGINEER、java engineer多种格式。
解决:在map函数中强制标准化:
// Java MapReduce 示例 public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] fields = line.split("\t"); if (fields.length > 2) { // 标准化职位名称:转小写、去首尾空格、合并多空格为单空格 String title = fields[2].toLowerCase().trim().replaceAll("\\s+", " "); context.write(new Text(title), new IntWritable(1)); } }额外动作:在清洗报告中增加「标准化前后对比」统计,如标准化前唯一职位数: 12,843,标准化后: 3,217,用数据说服业务方接受标准化规则。
6. 进阶技巧:用「ETL 健康度仪表盘」替代人工巡检,把被动救火变为主动防控
ETL 系统最怕的不是出错,而是出错后没人知道。我们曾经历过:某张 ODS 表连续 7 天未更新,业务方用着「过期数据」做决策,直到报表指标异常才上报。这份文档启发我们,把 ETL 监控从「日志文件 grep」升级为「健康度仪表盘」,核心是三个可量化、可告警、可归因的指标。
6.1 定义 ETL 健康度的黄金三角:时效性、完整性、一致性
我们不再问「ETL 跑没跑」,而是每天晨会看这三张表:
| 指标 | 计算逻辑 | 告警阈值 | 归因方法 |
|---|---|---|---|
| 时效性(Freshness) | DATEDIFF(hour, MAX(LastUpdate), GETDATE()) | > 24 小时告警 | 查ETL_Log表,定位最近一次失败任务的StepName和ErrorMessage |
| 完整性(Completeness) | (SELECT COUNT(*) FROM ODS.dbo.TableX) / (SELECT COUNT(*) FROM Source.dbo.TableX WHERE UpdateTime > DATEADD(day,-1,GETDATE())) | < 95% 告警 | 对比 ODS 与源表COUNT(*),再抽样 100 条ID检查是否存在 |
| 一致性(Consistency) | ABS(SUM(ODS_Amount) - SUM(DW_Amount)) / NULLIF(SUM(ODS_Amount),0) | > 0.1% 告警 | 执行SELECT * FROM ODS.dbo.Sales s LEFT JOIN DW.dbo.Fact_Sales f ON s.ID=f.SourceID WHERE f.ID IS NULL找漏同步记录 |
6.2 构建轻量级仪表盘:用 Power BI 连接 ETL 日志库,5 分钟搞定
我们把ETL_Log表(含TaskName,StartTime,EndTime,Status,RowCount,ErrorMessage)直接接入 Power BI,创建三个核心可视化:
- 时效性热力图:X 轴为
TaskName,Y 轴为Date,颜色深浅表示DATEDIFF(hour, EndTime, GETDATE()),红色越深越紧急; - 完整性趋势线:折线图展示每日
Completeness_Ratio,添加 95% 基准线,跌破即标红; - 一致性散点图:X 轴
ODS_Amount,Y 轴DW_Amount,理想状态是 45° 线,偏离越大点越红。
提示:仪表盘右上角固定显示「今日待办」——自动提取
ETL_Error_Log中Status='Unresolved'的记录,按Priority(高/中/低)排序。从那以后,我每次晨会第一件事就是打开这个仪表盘,而不是翻日志文件。它让我从「救火队员」变成了「防火队长」。希望帮到你。
本文还有配套的精品资源,点击获取