导读:ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。

作者:范钢 孙玄

来源:数仓宝贝库(ID:DataBaby_Family)

未经过任何加工的原始数据,往往存在着诸多的问题,数据质量不高,所以数据分析成本很高。原始数据必须要经过一个ETL过程,才能用于后续的分析挖掘工作。

更关键的是,数据来源的业务系统也是在不断地更新维护中的,任何一个变更都会对下游的数据分析程序产生巨大的影响。因此,有了ETL过程作为一个缓冲区,当上游的业务系统变更时,只需要对ETL过程进行相应变更,下游的数据分析就能够比较稳定,从而降低系统维护成本。

01 数据清洗

首先进行数据清洗,对原始数据中的错误予以纠正,或者对缺失数据进行补填。譬如,现在要建设一个增值税发票的数据中台。这时,系统从许多不同的来源采集与增值税发票相关的数据。当收集完这些原始数据以后,进行数据清洗工作。增值税发票的数据结构如下图所示。

▲增值税发票的数据结构图

在正常的增值税发票的数据结构中,每张进项发票都应当有至少一条发票明细。然而,可能由于采集的数据不一致,发票与明细经常不是同时到来,可能相差几天,造成用发票分析的数据与用发票明细分析的数据不一致。

这时,必须要先补填一个发票明细,虽然商品名称与数量不知道,但至少要保证发票明细的金额之和要等于发票金额,才不至于影响后续的分析质量。至于商品名称,可以暂时补填一个“未知商品”。这样,当该发票真正的发票明细到来时,再覆盖原有补填的明细。

此外,原本每张发票都应当有购方纳税人与销方纳税人,然而由于纳税人信息的基础数据来源于不同的系统,可能造成该发票的纳税人信息不在纳税人信息表中的情况。这时,必须要补填一条纳税人信息,使得发票表与纳税人能够对应上,不会造成数据无法关联而缺失数据。

同理,每个纳税人都应当有各自的税务机关、地域和行业,这些信息都可能缺失。对于税务机关和地域,可以通过纳税人社会信用代码中的内容进行推测。但是,行业信息是无法推测的。即使无法推测,也不能将其置为null,而是填一个默认值X99999,对应到行业表中的“未知行业”。

数据清洗的过程通过SparkSQL来实现。通过SparkSQL从原始表中查询数据,然后经过以下处理过程,最终写入ETL临时表中:

object ZzsfpJx {def main(args: Array[String]): Unit = {val task = LogUtils.start("zzsfpJxQd")try {val spark = SparkUtils.init("zzsfpJx")val ETLFPMAPNUM = PropertyFile.getProperty("ETLFPMAPNUM").toIntspark.udf.register("getJxfpId", (fpdm:String, fphm:String, kprq:String) => if(null==kprq) fpdm+"X"+fphm+"X" else fpdm+"X"+fphm+"X"+kprq)UdfRegister.fillNsr(spark)UdfRegister.fillSwjg(spark)UdfRegister.cutSL(spark)val result = spark.sql("SELECT getJxfpId(D.FPDM,D.FPHM,D.KPRQ) JXFP_ID,D.FPDM,D.FPHM,'YB' FP_LB,D.JE JE,cast(cutSL(D.SE/D.JE) as double) SL,D.SE SE,fillNsr(D.XFSBH) XF_NSRSBH, D.XFMC XF_NSRMC, fillNsr(D.GFSBH) GF_NSRSBH,D.GFMC GF_NSRMC,D.KPRQ, D.KPRQ RZSJ, D.XF_QXSWJG_DM SWJG_DM,from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss') CZSJ,NSR.SWJG_KEY GF_SWJG_DM,getSwjg(D.XF_QXSWJG_DM,fillNsr(D.XFSBH)) XF_SWJG_DM, case trim(D.fpzt_dm) when '0' then 'N' when '1' then 'N' else 'Y' end ZFBZ,'' SKM,'' SHRSBH,'' SHRMC,'' FHRSBH,'' FHRMC,'' QYD,'' SKPH, D.JSHJ,'' CZCH,'' CCDW,'' YSHWXX,D.BZ,D.tspz_dm as TSPZBZ,CASE WHEN length(trim(D.zfrq))>15 THEN D.zfrq ELSE NULL END ZFSJ FROM dzdz.DZDZ_FPXX_ZZSFP D JOIN DW.DW_DM_NSR NSR ON D.GFSBH = NSR.NSR_KEY and NSR.WDBZ='1'").repartition(ETLFPMAPNUM)DataFrameUtils.saveAppend(result, "etl", "etl_jxfp")LogUtils.end(task)} catch { case ex:Exception  => LogUtils.error(task, ex) }}
}

在以上SparkSQL程序中,首先从原始数据dzdz.DZDZ_FPXX_ZZSFP中查询数据,通过公用方法UdfRegister.fillNsr(spark)与UdfRegister.fillSwjg(spark)对纳税人与税务机关进行补填,保证发票在与纳税人信息、税务机关信息关联时不会因为数据为null而造成数据缺失。最终,将结果数据写入etl_jxfp的临时表中。

此外,在处理发票明细时加入了这样一段语句:

val result1 = spark.sql("SELECT getJxfpqdId(R.FPDM,R.FPHM,R.KPRQ,'00','1') JXFPQD_ID, getJxfpId(R.FPDM,R.FPHM,R.KPRQ) JXFP_ID ,1.0 HH,'YB' FP_LB,'无商品明细' WP_MC,'' WP_DW,'' WP_XH,1.0 WP_SL,R.JE DJ,R.JE, cast(cutSL(R.SL) as double) SL,R.SE,R.RZSJ, from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss') CZSJ,R.KPRQ,'00' QDBZ,'' SKPH,'' SFZHM,'' CD,'' HGZS,'' JKZMSH,'' SJDH,'' FDJHM, '' CJHM,'' DH,'' ZH,'' KHYH,'' DW,'' XCRS,0.0 JSHJ,'9999999999999999999' spbm "+s"FROM dzdz.DZDZ_HWXX_ZZSFP D RIGHT JOIN etl.ETL_JXFP R ON (D.FPDM = R.FPDM AND D.FPHM = R.FPHM) WHERE (D.FPDM is null or D.FPHM is null) and R.FP_LB='YB' ").repartition(ETLFPMAPNUM)DataFrameUtils.saveAppend(result1, "etl", "etl_jxfp_qd")

通过该语句在发票明细中加入了名为“无商品明细”的记录,保证发票明细、发票的金额与税额没有缺失,保障后续数据分析的准确性。

02 数据转换

以上一系列的数据清洗,可以有效杜绝因为缺失数据或关联不上造成的数据分析质量问题。接着,就是数据转换与集成。

数据中台的数据来源于不同的业务系统,因此数据格式、计算口径都可能存在差异。当把它们都抽取到数据中台以后,应当将其转换成统一口径,并规范计算口径。

譬如,如何识别代开发票,不同的系统有不同的判断逻辑,但经过数据转换以后,可以在表中增加一个“是否代开发票”字段,这样后续的分析业务就不必再去判断了,直接看该字段即可。此外,同样是税务机关代码,有的系统是9位,有的系统是11位,应该将它们都统一成11位。以上这些工作就是数据转换。

03 数据集成

清洗和转换工作完成以后,将相同或者相似的数据都集成在一起。譬如,从各个不同路径采集的纳税人信息,包括纳税人的基础信息、认证信息、核定信息、资格信息,都集成到了纳税人表中;从各个不同路径采集的各种不同的增值税发票,如增值税专票、增值税普票、机动车统一销售发票、电子发票等类型的发票,都统一集成到发票信息表中。

它们都来源于不同的业务系统,字段与类型都各不相同。因此,在集成的过程中,需要进行转换或补填,彼此格式一致,并最终存入同一张表中。譬如,其他发票都有发票明细,但机动车统一销售发票没有,因此需要给它补填一条发票明细,商品就是那辆汽车,金额与税额都是那张发票的金额与税额。

在具体设计实现上,就是为每一种发票都编写一个发票与发票明细的SparkSQL程序。它们分别从各自的原始数据中获取,但经过一个SQL语句的转换,最终都存入名为etl_jxfp与etl_jxfp_qd的发票与发票明细临时表中。

本文摘编自《架构真意:企业级应用架构设计方法论与实践》,经出版方授权发布。

延伸阅读

什么是ETL?一文掌握ETL设计过程相关推荐

  1. 一文追溯 ETL 的发展历程

    在这篇文章里,我们将追溯传统的ETL架构,然后看看现代ETL发展过程中的重大事件. 作者 | Ramindu De Silva 译者 | 弯月,责编 | 郭芮 头图 | CSDN 下载自东方 IC 出 ...

  2. 【Elasticsearch】2021 年的顶级 ETL 工具......以及对 ETL 说“不”的理由

    1.概述 翻译:2021 年的顶级 ETL 工具-以及对 ETL 说"不"的理由 为您的企业找到合适的 ETL 工具至关重要.ETL 从源中提取数据(提取),根据需求进行更改(转换 ...

  3. 计算机word教案设计,Word文档教学设计

    Word文档教学设计 [教学目的与要求] (1)学会对文章进行段落的对齐.缩进和行距调整. (2)通过实际操作,培养学生的动手能力.探知能力. [课时安排] 建议2~3课时. [教学重点与难点] 段落 ...

  4. HTML5期末大作业:咖啡文食网站设计——代码质量好-咖啡文食品网5页面模板化(1页) HTML+CSS+JavaScript

    HTML5期末大作业:咖啡文食网站设计--代码质量好-咖啡文食品网5页面模板化(1页) HTML+CSS+JavaScript 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. ...

  5. 墨器杯垫 文创商品设计特优

    教育部昨举行「102年国立馆所文创商品设计比赛」颁奖典礼,台北科技大学创新设计研究所硕士生谢镇宇,为TW艺术教育馆设计「墨器」杯垫,取「默契」谐音,用5片压克力板,展现水墨画层层渲染效果,增加立体视觉 ...

  6. VC 多文档用户界面设计及各个文档之间的切换

    VC 多文档用户界面设计及各个文档之间的切换 用Delphi.VB.Windows Form(Visual C#)等称之为RAD(Rapid Application Development)的开发工具 ...

  7. 电子产品设计流程_“创意点亮警大”首届文创产品设计大赛等你来战!

    你是否有着匠心独具的艺术创意 你是否期待着自己的作品风靡校园 你是否梦想着为警大亲手设计一款网红文创产品 首届"创意·点亮警大"文化创意产品设计大赛来了! 为更好地开发制作优质文化 ...

  8. 【天光学术】艺术论文:传统凤鸟图形在博物馆文创产品设计中的运用

    摘 要 伴随中国成为世界第二大经济体,与此所带来的国民对于文化的消费与体验变得日益重要与突出,以文化为消费对象并作为传达载体的创意产业是拉动中国未来经济发展的后发力量.凤鸟图形自古以来都是汉民族的象征 ...

  9. 需求文档和设计文档的区别

    需求文档和设计文档的区别 需求文档是根据用户需求转化而来的技术实现需求,需要针对用户提出的产品目标进行细分,总结出具体的每一个功能点,再针对每一个功能点细分为各种不同的操作流程,对每一个操作流程进行技 ...

  10. java xml 合并_Java中合并XML文档的设计与实现

    为了读写XML文件,需要导入如下JAVA包,"//"后为注释说明,笔者的环境是JDK1.3.1,在JDK 1.4.0中测试也通过. Import java.io. *; //Jav ...

最新文章

  1. 当 Redis 发生高延迟时,到底发生了什么
  2. 联想手机android系统耗电,联想 K900 Android 4.2 手机续航能力实测
  3. python什么环境_什么是Python?(基础环境建设),NO2,搭建
  4. python—类和对象之浅拷贝和深拷贝详细讲解
  5. (step6.3.2)hdu 1068(Girls and Boys——二分图的最大独立集)
  6. 判定是否过拟合、欠拟合的一种方式
  7. NVIDIA 控制面板闪退问题解决
  8. 2010年软件评测师真题精选
  9. java程序员 英文简历_Java程序员英文简历
  10. 一起学ORBSLAM2(9)ORBSLAM的PNP解决方案
  11. Windows常用快捷键和Windows CMD命令大全
  12. 数据查询网站汇总——自用
  13. 安卓手机优化,修改build.prop
  14. 春秋杯CTF2022 WP
  15. 九连环的递归实现,以及数列通项
  16. java统计字数_JAVA 仿 MS word 字数统计
  17. 离线安装Python软件包的方法
  18. UCOS学习(一)——前后台系统、RTOS系统
  19. 动态规划题目集合——贰
  20. 写一款汽车维修保养软件,让维修保养管理更加轻松,JavaScript 作用域

热门文章

  1. Qt文档阅读笔记-QFuture官方解析及实例
  2. Spring Cloud笔记-Maven构建父子项目
  3. 设置webhook_webhook工具实现
  4. java 接口初始化_Java类的初始化 | 学步园
  5. 动词ing基本用法_如果实在分不清英语动名词和现在分词,那就直接学习-ing分词...
  6. 商务英语计算机,BEC商务英语
  7. python 列表副本_列表副本不工作?
  8. python对应的岗位_隐式相对导入如何在Python中工作?
  9. linux 进程监控命令2——ps
  10. 模拟攻击者利用“域前置”(Domain Fronting)技术逃避审查(重定向、CDN)