关于数据仓库:数仓建设保姆级教程离线和实时一网打尽理论实战

12次阅读

共计 65355 个字符,预计需要花费 164 分钟才能阅读完成。

数仓建设保姆级教程,离线和实时一网打尽(实践 + 实战)

本文纲要:

因内容较多,带目录的 PDF 查看是比拟不便的:

数仓建设保姆级教程 PDF 文档

一、数仓基本概念

1. 数据仓库架构

咱们在谈数仓之前,为了让大家有直观的意识,先来谈数仓架构,“架构 ”是什么?这个问题素来就没有一个精确的答案。这里咱们援用一段话:在软件行业,一种被广泛承受的架构定义是 指零碎的一个或多个构造。构造中包含软件的构建(构建是指软件的设计与实现),构建的内部能够看到属性以及它们之间的互相关系

这里参考此定义,把数据仓库架构了解成形成数据仓库的组件及其之间的关系,画出上面的数仓架构图:

上图中显示的整个数据仓库环境包含操作型零碎和数据仓库零碎两大部分。操作型零碎的数据由各种模式的业务数据组成,这些数据通过抽取、转换和装载(ETL)过程进入数据仓库零碎。

任何事物都是随着工夫的演进变得越来越欠缺,当然也是越来越简单,数仓也不例外。在数据仓库技术演化过程中,产生了几种次要的架构办法,包含 数据集市架构 Inmon 企业信息工厂架构Kimball 数据仓库架构 混合型数据仓库架构。这几种架构咱们前面再讲,接下来看下数仓的基本概念。

2. 数据仓库概念

英文名称为 Data Warehouse,可简写为 DW 或 DWH。数据仓库的目标是 构建面向剖析的集成化数据环境,为企业提供决策反对(Decision Support)。它出于剖析性报告和决策反对目标而创立。

数据仓库自身并不“生产”任何数据,同时本身也不须要“生产”任何的数据,数据来源于内部,并且凋谢给内部利用,这也是为什么叫“仓库”,而不叫“工厂”的起因。

1) 基本特征

数据仓库是 面向主题的 集成的 非易失的 时变的 数据汇合,用以反对管理决策。

  1. 面向主题:

传统数据库中,最大的特点是面向利用进行数据的组织,各个业务零碎可能是互相拆散的。而数据仓库则是面向主题的。主题是一个形象的概念,是较高层次上企业信息系统中的数据综合、归类并进行剖析利用的形象。在逻辑意义上,它是对应企业中某一宏观剖析畛域所波及的剖析对象。

  1. 集成性:

通过对扩散、独立、异构的数据库数据进行 抽取、清理、转换和汇总 便失去了数据仓库的数据,这样保障了数据仓库内的数据对于整个企业的一致性。

数据仓库中的综合数据不能从原有的数据库系统间接失去。因而在数据进入数据仓库之前,必然要通过对立与综合,这一步是数据仓库建设中最要害、最简单的一步,所要实现的工作有:

  • 要对立源数据中所有矛盾之处,如字段的同名异义、异名同义、单位不对立、字长不统一,等等。
  • 进行数据综合和计算。数据仓库中的数据综合工作能够在从原有数据库抽取数据时生成,但许多是在数据仓库外部生成的,即进入数据仓库当前进行综合生成的。

下图阐明一个保险公司综合数据的简略处理过程,其中数据仓库中与“保险”主题无关的数据来自于多个不同的操作型零碎。这些零碎外部数据的命名可能不同,数据格式也可能不同。把不同起源的数据存储到数据仓库之前,须要去除这些不统一。

  1. 非易失性(不可更新性):

数据仓库的数据反映的是一段相当长的工夫内 历史数据的内容,是不同时点的数据库快照的汇合,以及基于这些快照进行统计、综合和重组的导出数据。

数据非易失性次要是针对利用而言。数据仓库的用户对数据的操作大多是数据查问或比较复杂的开掘,一旦数据进入数据仓库当前,个别状况下被较长时间保留。数据仓库中个别有大量的查问操作,但批改和删除操作很少。因而,数据经加工和集成进入数据仓库后是极少更新的,通常只须要定期的加载和更新

  1. 时变性:

数据仓库蕴含各种粒度的历史数据。数据仓库中的数据可能与某个特定日期、星期、月份、季度或者年份无关。数据仓库的目标是通过剖析企业过来一段时间业务的经营情况,开掘其中暗藏的模式。尽管 数据仓库的用户不能批改数据,但并不是说数据仓库的数据是永远不变的。剖析的后果只能反映过来的状况,当业务变动后,挖掘出的模式会失去时效性。因而数据仓库的数据须要更新,以适应决策的须要。从这个角度讲,数据仓库建设是一个我的项目,更是一个过程。数据仓库的数据随工夫的变动体现在以下几个方面:

(1)数据仓库的数据时限个别要远远长于操作型数据的数据时限。
(2)操作型零碎存储的是以后数据,而数据仓库中的数据是历史数据。
(3)数据仓库中的数据是依照工夫程序追加的,它们都带有工夫属性。

3. 为什么要有数据仓库

先来看下数据仓库的数据从哪里来,最终要到哪里去?

通常数据仓库的数据来自各个业务利用零碎 。业务零碎中的数据模式多种多样,可能是 Oracle、MySQL、SQL Server 等关系数据库里的结构化数据,可能是文本、CSV 等立体文件或 Word、Excel 文档中的数据,还可能是 HTML、XML 等自描述的半结构化数据。这些业务数据通过一系列的数据抽取、转换、荡涤,最终以一种对立的格局装载进数据仓库。数据仓库里的数据作为剖析用的数据源, 提供给前面的即席查问、剖析零碎、数据集市、报表零碎、数据挖掘零碎等

这时咱们就想了,为什么不能把业务零碎的数据间接拿来供即席查问、剖析零碎、报表零碎等应用呢,为什么要通过数据仓库这一步?实际上在数仓呈现之前,的确是这么做的,然而有很多数据分析的先驱者过后曾经发现,简略的“间接拜访”形式很难良好工作,这样做的失败案例不可胜数。上面列举一些间接拜访业务零碎无奈工作的起因:

  • 某些业务数据因为平安或其余因素不能间接拜访。
  • 业务零碎的版本变更很频繁,每次变更都须要重写剖析零碎并从新测试。
  • 很难建设和保护汇总数据来源于多个业务零碎版本的报表。
  • 业务零碎的列名通常是硬编码,有时仅仅是无意义的字符串,这让编写剖析零碎更加艰难。
  • 业务零碎的数据格式,如日期、数字的格局不对立。
  • 业务零碎的表构造为事务处理性能而优化,有时并不适宜查问与剖析。
  • 没有适当的形式将有价值的数据合并进特定利用的数据库。
  • 没有适当的地位存储元数据。
  • 用户须要看到的显示数据字段,有时在数据库中并不存在。
  • 通常事务处理的优先级比剖析零碎高,所以如果剖析零碎和事务处理运行在同一硬件之上,剖析零碎往往性能很差。
  • 有误用业务数据的危险。
  • 极有可能影响业务零碎的性能。

只管须要减少软硬件的投入,但建设独立数据仓库与间接拜访业务数据相比,无论是老本还是带来的益处,这样做都是值得的。随着处理器和存储老本的逐年升高,数据仓库计划的劣势更加显著,在经济上也更具可行性。

4. 数据仓库与数据库的区别

数据库与数据仓库的区别理论讲的是 OLTP 与 OLAP 的区别。

操作型解决,叫联机事务处理 OLTP(On-Line Transaction Processing,),也能够称面向交易的解决零碎,它是针对具体业务在数据库联机的日常操作,通常对多数记录进行查问、批改。用户较为关怀操作的响应工夫、数据的安全性、完整性和并发反对的用户数等问题。传统的数据库系统作为数据管理的次要伎俩,次要用于操作型解决,像 Mysql,Oracle 等关系型数据库个别属于 OLTP。

剖析型解决,叫联机剖析解决 OLAP(On-Line Analytical Processing)个别针对某些主题的历史数据进行剖析,反对管理决策。

首先要明确,数据仓库的呈现,并不是要取代数据库。数据库是面向事务的设计,数据仓库是面向主题设计的。数据库个别存储业务数据,数据仓库存储的个别是历史数据。

数据库设计是尽量避免冗余,个别针对某一业务利用进行设计,比方一张简略的 User 表,记录用户名、明码等简略数据即可,合乎业务利用,然而不合乎剖析。数据仓库在设计是无意引入冗余,按照剖析需要,剖析维度、剖析指标进行设计

数据库是为捕捉数据而设计,数据仓库是为剖析数据而设计

以银行业务为例。数据库是事务零碎的数据平台,客户在银行做的每笔交易都会写入数据库,被记录下来,这里,能够简略地了解为用数据库记账。数据仓库是剖析零碎的数据平台,它从事务零碎获取数据,并做汇总、加工,为决策者提供决策的根据。比方,某银行某分行一个月产生多少交易,该分行以后贷款余额是多少。如果贷款又多,生产交易又多,那么该地区就有必要设立 ATM 了。

显然,银行的交易量是微小的,通常以百万甚至千万次来计算。事务零碎是实时的,这就要求时效性,客户存一笔钱须要几十秒是无法忍受的,这就要求数据库只能存储很短一段时间的数据。而剖析零碎是预先的,它要提供关注时间段内所有的无效数据。这些数据是海量的,汇总计算起来也要慢一些,然而,只有可能提供无效的剖析数据就达到目标了。

数据仓库,是在数据库曾经大量存在的状况下,为了进一步开掘数据资源、为了决策须要而产生的,它决不是所谓的“大型数据库”

5. 数据仓库分层架构

依照数据流入流出的过程,数据仓库架构可分为:源数据 数据仓库 数据利用

数据仓库的数据来源于不同的源数据,并提供多样的数据利用,数据自下而上流入数据仓库后向下层凋谢利用,而数据仓库只是两头集成化数据管理的一个平台。

源数据:此层数据无任何更改,间接沿用外围零碎数据结构和数据,不对外开放;为长期存储层,是接口数据的长期存储区域,为后一步的数据处理做筹备。

数据仓库:也称为细节层,DW 层的数据应该是统一的、精确的、洁净的数据,即对源零碎数据进行了荡涤(去除了杂质)后的数据。

数据利用:前端利用间接读取的数据源;依据报表、专题剖析需要而计算生成的数据。

数据仓库从各数据源获取数据及在数据仓库内的数据转换和流动都能够认为是 ETL(抽取 Extra, 转化 Transfer, 装载 Load)的过程,ETL 是数据仓库的流水线,也能够认为是数据仓库的血液,它维系着数据仓库中数据的推陈出新,而数据仓库日常的治理和保护工作的大部分精力就是放弃 ETL 的失常和稳固。

那么为什么要数据仓库进行分层呢?

  • 用空间换工夫,通过大量的预处理来晋升利用零碎的用户体验(效率),因而数据仓库会存在大量冗余的数据;不分层的话,如果源业务零碎的业务规定发生变化将会影响整个数据荡涤过程,工作量微小。
  • 通过数据分层治理能够 简化数据荡涤的过程,因为把原来一步的工作分到了多个步骤去实现,相当于把一个简单的工作拆成了多个简略的工作,把一个大的黑盒变成了一个白盒,每一层的解决逻辑都绝对简略和容易了解,这样咱们比拟容易保障每一个步骤的正确性,当数据产生谬误的时候,往往咱们只须要部分调整某个步骤即可。

6. 次要数据仓库架构

通过下面的内容咱们大略理解数仓的概念,接下来就看下数仓的几种演进架构。

1. 数据集市架构

数据集市是按主题域组织的数据汇合,用于反对部门级的决策。有两种类型的数据集市:独立数据集市 隶属数据集市

1) 独立数据集市

独立数据集市集中于部门所关怀的繁多主题域,数据以部门为根底部署,毋庸思考企业级别的信息共享与集成。例如,制作部门、人力资源部门和其余部门都各自有他们本人的数据集市。

长处:因为一个部门的业务绝对于整个企业要简略,数据量也小得多,所以部门的独立数据集市具备周期短、见效快的特点。

毛病

  • 从业务角度看,当部门的剖析需要扩大,或者须要剖析跨部门或跨主题域的数据时,独立数据市场会显得力不从心。
  • 当数据存在歧义,比方同一个产品,在 A 部门和 B 部门的定义不同时,将无奈在部门间进行信息比拟。
  • 每个部门应用不同的技术,建设不同的 ETL 的过程,解决不同的事务零碎,而在多个独立的数据集市之间还会存在数据的穿插与重叠,甚至会有数据不统一的状况。
2) 隶属数据集市

隶属数据集市的数据来源于数据仓库。数据仓库里的数据通过整合、重构、汇总后传递给隶属数据集市。

建设隶属数据集市的益处次要有:

  • 性能:当数据仓库的查问性能呈现问题,能够思考建设几个隶属数据集市,将查问从数据仓库移出到数据集市。
  • 平安:每个部门能够齐全管制他们本人的数据。
  • 数据统一:因为每个数据集市的数据起源都是同一个数据仓库,无效打消了数据不统一的状况。

2. Inmon 企业工厂架构

上图的前两步不过多介绍,间接从第三步开始。

企业级数据仓库:是该架构中的外围组件。正如 Inmon 数据仓库所定义的,企业级数据仓库是一个细节数据的集成资源库。其中的数据以最低粒度级别被捕捉,存储在满足三范式设计的关系数据库中。

部门级数据集市:是面向主题数据的部门级视图,数据从企业级数据仓库获取。数据在进入部门数据集市时可能进行聚合。数据集市应用多维模型设计,用于数据分析。重要的一点是,所有的报表工具、BI 工具或其余数据分析利用都从数据集市查问数据,而不是间接查问企业级数据仓库。

3. Kimball 数据仓库架构

比照上一张图能够看到,Kimball 与 Inmon 两种架构的次要区别在于外围数据仓库的设计和建设。

Kimball 的数据仓库蕴含高粒度的企业数据,应用多维模型设计,这也意味着 数据仓库由星型模式的维度表和事实表形成。剖析零碎或报表工具能够间接拜访多维数据仓库里的数据。

在此架构中的数据集市也与 Inmon 中的不同。这里的 数据集市是一个逻辑概念,只是多维数据仓库中的主题域划分,并没有本人的物理存储,也能够说是虚构的数据集市。

4. 混合型数据仓库架构

所谓的混合型构造,指的是在一个数据仓库环境中,联结应用 Inmon 和 Kimball 两种架构

从架构图能够看到,这种架构将 Inmon 办法中的数据集市局部替换成了一个多维数据仓库,而数据集市则是多维数据仓库上的逻辑视图。

应用这种架构的益处是:既能够利用规范化设计打消数据冗余,保证数据的粒度足够细;又能够利用多维构造更灵便地在企业级实现报表和剖析。

7. 数据仓库元数据的治理

元数据(Meta Date),次要记录数据仓库中模型的定义、各层级间的映射关系、监控数据仓库的数据状态及 ETL 的工作运行状态。个别会通过元数据资料库(Metadata Repository)来对立地存储和治理元数据,其次要目标是使数据仓库的设计、部署、操作和治理能达成协同和统一。

元数据是数据仓库管理系统的重要组成部分,元数据管理是企业级数据仓库中的要害组件,贯通数据仓库构建的整个过程,间接影响着数据仓库的构建、应用和保护。

  • 构建数据仓库的次要步骤之一是 ETL。这时元数据将施展重要的作用,它定义了源数据系统到数据仓库的映射、数据转换的规定、数据仓库的逻辑构造、数据更新的规定、数据导入历史记录以及装载周期等相干内容。数据抽取和转换的专家以及数据仓库管理员正是通过元数据高效地构建数据仓库。
  • 用户在应用数据仓库时,通过元数据拜访数据,明确数据项的含意以及定制报表。
  • 数据仓库的规模及其复杂性离不开正确的元数据管理,包含减少或移除内部数据源,扭转数据荡涤办法,管制出错的查问以及安顿备份等。

元数据可分为技术元数据和业务元数据。技术元数据 为开发和治理数据仓库的 IT 人员应用,它形容了与数据仓库开发、治理和保护相干的数据,包含数据源信息、数据转换形容、数据仓库模型、数据荡涤与更新规定、数据映射和拜访权限等。而 业务元数据 为管理层和业务剖析人员服务,从业务角度形容数据,包含商务术语、数据仓库中有什么数据、数据的地位和数据的可用性等,帮忙业务人员更好地了解数据仓库中哪些数据是可用的以及如何应用。

由上可见,元数据不仅定义了数据仓库中数据的模式、起源、抽取和转换规则等,而且是整个数据仓库零碎运行的根底,元数据把数据仓库零碎中各个涣散的组件分割起来,组成了一个有机的整体

8. 数仓常见术语解析

本文档首发于公众号【五分钟学大数据

本大节构造如下图所示:

1. 数仓名词解释

1. 实体

实体是指附丽的主体,就是咱们剖析的一个对象,比方咱们剖析商品的销售状况,如华为手机近半年的销售量是多少,那华为手机就是一个实体;咱们剖析用户的活跃度,用户就是一个实体。当然实体也能够事实中不存在的,比方虚构的业务对象,流动,会员等都可看做一个实体。

实体的存在是为了业务剖析,作为剖析的一个筛选的维度,领有形容本人的属性,自身具备可剖析的价值

2. 维度

维度就是对待问题的角度,剖析业务数据,从什么角度剖析,就建设什么样的维度。所以维度就是要对数据进行剖析时所用的一个量,比方你要剖析产品销售状况,你能够抉择按商品类别来进行剖析,这就形成一个维度,把所有商品类别汇合在一起,就形成了维度表。

3. 度量

度量是业务流程节点上的一个数值。比方销量,价格,老本等等。

事实表中的度量可分为三类:齐全可加,半可加,不可加

  1. 齐全可加的度量是最灵便,最有用的,比如说销量,销售额等,可进行任意维度汇总;
  2. 半可加的度量能够对某些维度汇总,但不能对所有维度汇总,差额是常见的半可加度量,它除了工夫维度外,能够跨所有维度进行加法操作;
  3. 还有一种是齐全不可加的,例如:比率。对于这类非可加度量,一种好的办法是,尽可能存储非可加度量的齐全可加重量,并在计算出最终的非可加事实前,将这些重量汇总到最终的后果集中。

4. 粒度

粒度就是业务流程中对度量的单位,比方商品是按件记录度量,还是按批记录度量。

在数仓建设中,咱们说这是用户粒度的事实表,那么表中每行数据都是一个用户,无反复用户;例如还有销售粒度的表,那么表中每行都是一条销售记录。

抉择适合的粒度级别是数据仓库建设好坏的重要要害内容,在设计数据粒度时,通常需重点思考以下因素:

  1. 要承受的剖析类型、可承受的数据最低粒度和能存储的数据量;
  2. 粒度的档次定义越高,就越不能在该仓库中进行更粗疏的剖析;
  3. 如果存储资源有肯定的限度,就只能采纳较高的数据粒度划分;
  4. 数据粒度划分策略肯定要保障:数据的粒度的确可能满足用户的决策分析须要,这是数据粒度划分策略中最重要的一个准则

    5. 口径

口径就是取数逻辑(如何取数的),比方 要取的数 是 10 岁以下儿童中男孩的均匀身高,这就是统计的口径。

6. 指标

指标是口径的掂量值,也就是最初的后果。比方最近七天的订单量,一个促销流动的购买转化率等。

一个指标具体到计算施行,次要有以下几局部组成:

  • 指标加工逻辑,比方 count ,sum, avg
  • 维度,比方按部门、地区进行指标统计,对应 sql 中的 group by
  • 业务限定 / 修饰词,比方以不同的领取渠道来算对应的指标,微信领取的订单退款率,支付宝领取的订单退款率。对应 sql 中的 where。

除此之外,指标自身还能够衍生、派生出更多的指标,基于这些特点,能够将指标进行分类:

  • 原子指标:根本业务事实,没有业务限定、没有维度。比方订单表中的订单量、订单总金额都算原子指标;

业务方更关怀的指标,是有理论业务含意,能够间接取数据的指标。比方店铺近 1 天订单领取金额就是一个派生指标,会被间接在产品上展现给商家看。
\
然而这个指标却不能间接从数仓的对立中间层里取数(因为没有现成的事实字段,数仓提供的个别都是大宽表)。须要有一个桥梁连接数仓中间层和业务方的指标需要,于是便有了派生指标

  • 派生指标 维度 + 修饰词 + 原子指标。店铺近 1 天订单领取金额中店铺是维度,近 1 天是一个工夫类型的修饰词,领取金额是一个原子指标;

维度:察看各项指标的角度;
\
修饰词:维度的一个或某些值,比方维度性别下,男和女就是 2 种修饰词。

  • 衍生指标 :比方某一个促销流动的转化率就是衍生指标,因为须要 促销投放人数指标 促销订单数指标 进行计算得出。

7. 标签

标签是人为设定的、依据业务场景需要,对指标对象使用肯定的算法失去的高度精炼的特色标识。可见标签是通过人为再加工后的后果,如网红、白富美、萝莉。对于有歧义的标签,咱们外部可进行标签辨别,比方:苹果,咱们能够定义苹果指的是水果,苹果手机才指的是手机。

8. 天然键

由事实中曾经存在的属性组成的键,它在业务概念中是惟一的,并具备肯定的业务含意,比方商品 ID,员工 ID。

以数仓角度看,来自于业务零碎的标识符就是天然键,比方业务库中员工的编号。

9. 长久键

放弃永久性不会发生变化。有时也被叫做超自然长久键。比方身份证号属于长久键。

天然键和长久键区别:举个例子就明确了,比如说公司员工到职之后又从新入职,他的天然键也就是员工编号产生了变动,然而他的长久键身份证号是不变的。

10. 代理键

就是不具备业务含意的键。代理键有许多其余的称说:无意义键、整数键、非天然键、人工键、合成键等。

代理键就是简略的以依照程序序列生产的整数示意。产品行的第 1 行代理键为 1,则下一行的代理键为 2,如此进行。代理键的作用仅仅是连贯维度表和事实表

11. 进化维度

进化维度,就是那些看起来像是事实表的一个维度关键字,但实际上并没有对应的维度表,就是维度属性存储到事实表中,这种存储到事实表中的维度列被称为进化维度。与其余存储在维表中的维度一样,进化维度也能够用来进行事实表的过滤查问、实现聚合操作等。

那么到底怎么定义进化维度呢?比如说订单 id,这种量级很大的维度,没必要用一张维度表来进行存储,而咱们进行数据查问或者数据过滤的时候又十分须要,所以这种就冗余在事实表外面,这种就叫进化维度,citycode 这种咱们也会冗余在事实表外面,然而 它有对应的维度表,所以它不是进化维度

12. 下钻

这是在数据分析中常见的概念,下钻能够了解成减少维的档次,从而能够 由粗粒度到细粒度来察看数据,比方对产品销售状况剖析时,能够沿着工夫维从年到月到日更细粒度的察看数据。从年的维度能够下钻到月的维度、日的维度等。

13. 上卷

晓得了下钻,上卷就容易了解了,它俩是相逆的操作,所以 上卷能够了解为删掉维的某些层,由细粒度到粗粒度察看数据的操作或沿着维的档次向上聚合汇总数据。

14. 数据集市

数据集市(Data Mart),也叫数据市场,数据集市就是满足特定的部门或者用户的需要,依照多维的形式进行存储,包含定义维度、须要计算的指标、维度的档次等,生成面向决策分析需要的数据立方体。其实就是从数据仓库中抽取进去的一个小合集。

2. 数仓名词之间关系

1. 实体表,事实表,维度表之间的关系

在 Kimball 维度建模中有维度与事实,在 Inmon 范式建模中有实体与关系,如果咱们离开两种建模形式看这些概念比拟容易了解。然而目前也呈现了不少混合建模形式,两种建模形式联合起来看,这些概念是不是容易记忆凌乱,尤其事实表和实体表,它们之间到底有怎么区别与分割,先看下它们各自概念:

  1. 维度表:维度表能够看成是用户用来剖析一个事实的窗口,它外面的数据应该是对事实的各个方面形容,比方工夫维度表,地区维度表,维度表是事实表的一个剖析角度。
  2. 事实表:事实表其实就是通过各种维度和一些指标值的组合来确定一个事实的,比方通过工夫维度,地区组织维度,指标值能够去确定在某时某地的一些指标值怎么样的事实。事实表的每一条数据都是几条维度表的数据和指标值交汇而失去的。
  3. 实体表:实体表就是一个理论对象的表,实体表放的数据肯定是一条条客观存在的事物数据,比如说各种商品,它就是客观存在的,所以能够将其设计一个实体表。实时表只形容各个事物,并不存在具体的事实,所以也有人称实体表是无事实的事实表。

举个例子:比如说手机商场中有苹果手机,华为手机等各品牌各型号的手机,这些数据能够组成一个 手机实体表 ,然而表中没有可度量的数据。某天苹果手机卖了 15 台,华为手机卖了 20 台,这些手机销售数据属于事实,组成一个 事实表 。这样就能够应用 日期维度表 地区维度表 对这个事实表进行各种维度剖析。

2. 指标与标签的区别

  • 概念不同

指标 是用来定义、评估和形容特定事物的一种规范或形式。比方:新增用户数、累计用户数、用户沉闷率等是掂量用户倒退状况的指标;

标签 是人为设定的、依据业务场景需要,对指标对象使用肯定的算法失去的高度精炼的特色标识。可见标签是通过人为再加工后的后果,如网红、白富美、萝莉。

  • 形成不同

指标名称 是对事物质与量两方面特点的命名;指标取值是指标在具体工夫、地区、条件下的数量体现,如人的体重,指标名称是体重,指标的取值就是 120 斤;

标签名称 通常都是形容词或形容词 + 名词的构造,标签个别是不可量化的,通常是孤立的,除了根底类标签,通过肯定算法加工进去的标签个别都没有单位和量纲。如将超过 200 斤的称为大瘦子。

  • 分类不同

对指标的分类

依照指标计算逻辑,能够将指标分为原子指标、派生指标、衍生指标三种类型;

依照对事件形容内容的不同,分为过程性指标和后果性指标;

对标签的分类

依照标签的变动性分为动态标签和动静标签;

依照标签的指代和评估指标的不同,可分为定性标签和定量标签;

指标 最善于的利用是监测、剖析、评估和建模。
\
标签 最善于的利用是标注、刻画、分类和特征提取。
\
特地须要指出的是,因为对后果的标注也是一种标签,所以在自然语言解决和机器学习相干的算法利用场景下,标签对于监督式学习有重要价值,只是单纯的指标难以做到的。而指标在任务分配、绩效治理等畛域的作用,也是标签无奈做到的。

3. 维度和指标区别与分割

维度就是数据的察看角度,即从哪个角度去剖析问题,对待问题。

指标就是从维度的根底下来衡算这个后果的值。

维度个别是一个离散的值,比方工夫维度上每一个独立的日期或地区,因而统计时,能够把维度雷同记录的聚合在一起,利用聚合函数做累加、均值、最大值、最小值等聚合计算。

指标就是被聚合的通计算,即聚合运算的后果,个别是一个间断的值。

4. 天然键与代理键在数仓的应用区别

数仓工具箱中说 维度表的惟一主键应该是代理键而不应该是天然键。有时建模人员不违心放弃应用天然键,因为他们心愿与操作型代码查问事实表,而不心愿与维度表做连贯操作。然而,应该防止应用蕴含业务含意的多维键,因为不论咱们做出任何假如最终都可能变得有效,因为咱们控制不了业务库的变动。

所以数据仓库中维度表与事实表的每个连贯应该基于无理论含意的整数代理键。防止应用天然键作为维度表的主键

5. 数据集市和数据仓库的关系

数据集市是企业级数据仓库的一个子集,他次要面向部门级业务,并且只面向某个特定的主题。为了解决灵活性和性能之间的矛盾,数据集市就是数据仓库体系结构中减少的一种小型的部门或工作组级别的数据仓库。数据集市存储为特定用户事后计算好的数据,从而满足用户对性能的需要。数据集市能够在肯定水平上缓解拜访数据仓库的瓶颈。

数据集市和数据仓库的次要区别:数据仓库是企业级的,能为整个企业各个部门的运行提供决策反对伎俩;而数据集市则是一种微型的数据仓库, 它通常有更少的数据, 更少的主题区域, 以及更少的历史数据, 因而是部门级的,个别只能为某个部分范畴内的管理人员服务,因而也称之为部门级数据仓库。

文章都会首发在公众号【五分钟学大数据】

二、离线数仓建设外围

数据仓库的外围是展示层和提供优质的服务。ETL 及其标准、分层等所做的一切都是为了一个更清晰易用的展示层。

1. 数仓分层

数仓分层的准则

  1. 为便于数据分析,要屏蔽底层简单业务,简略、残缺、集成的将数据裸露给剖析层。
  2. 底层业务变动与下层需要变动对模型冲击最小化,业务零碎变动影响减弱在根底数据层,联合自上而下的建设办法减弱需要变动对模型的影响。
  3. 高内聚松耦合,即主题之内或各个残缺意义的零碎内数据的高内聚,主题之间或各个残缺意义的零碎间数据的松耦合。
  4. 构建仓库根底数据层,使底层业务数据整合工作与下层利用开发工作相隔离,为仓库大规模开发奠定根底 仓库档次更加清晰,对外裸露数据更加对立。

个别采纳如下分层构造:

1. 数据源层:ODS(Operational Data Store)

ODS 层,是最靠近数据源中数据的一层,为了思考后续可能须要追溯数据问题,因而对于这一层就不倡议做过多的数据荡涤工作,一成不变地接入原始数据即可,至于数据的去噪、去重、异样值解决等过程能够放在前面的 DWD 层来做。

2. 数据仓库层:DW(Data Warehouse)

数据仓库层是咱们在做数据仓库时要外围设计的一层,在这里,从 ODS 层中取得的数据依照主题建设各种数据模型。

DW 层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和 DWS(Data WareHouse Servce)层。

1) 数据明细层:DWD(Data Warehouse Detail)

该层个别放弃和 ODS 层一样的数据粒度,并且提供肯定的数据质量保证。DWD 层要做的就是将数据清理、整合、规范化、脏数据、垃圾数据、标准不统一的、状态定义不统一的、命名不标准的数据都会被解决

同时,为了进步数据明细层的易用性,该层会采纳一些维度进化手法,将维度进化至事实表中,缩小事实表和维表的关联

另外,在该层也会做一部分的数据聚合,将雷同主题的数据会集到一张表中,进步数据的可用性。

2) 数据中间层:DWM(Data WareHouse Middle)

该层会在 DWD 层的数据根底上,数据做轻度的聚合操作,生成一系列的两头表,晋升公共指标的复用性,缩小反复加工。

直观来讲,就是对通用的外围维度进行聚合操作,算出相应的统计指标

在理论计算中,如果间接从 DWD 或者 ODS 计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因而个别的做法是,在 DWM 层先计算出多个小的两头表,而后再拼接成一张 DWS 的宽表。因为宽和窄的界线不易界定,也能够去掉 DWM 这一层,只留 DWS 层,将所有的数据再放在 DWS 亦可。

3) 数据服务层:DWS(Data WareHouse Servce)

DWS 层为公共汇总层,会进行轻度汇总,粒度比明细数据稍粗,基于 DWD 层上的根底数据,整合汇总成剖析某一个主题域的服务数据,个别是宽表。DWS 层应笼罩 80% 的利用场景。又称数据集市或宽表。

依照业务划分,如主题域流量、订单、用户等,生成字段比拟多的宽表,用于提供后续的业务查问,OLAP 剖析,数据散发等。

一般来讲,该层的数据表会绝对比拟少,一张表会涵盖比拟多的业务内容,因为其字段较多,因而个别也会称该层的表为宽表。

3. 数据应用层:APP(Application)

在这里,次要是提供给数据产品和数据分析应用的数据,个别会寄存在 ES、PostgreSql、Redis 等零碎中供线上零碎应用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘应用。比方咱们常常说的报表数据,个别就放在这里。

4. 维表层:DIM(Dimension)

如果维表过多,也可针对维表设计独自一层,维表层次要蕴含两局部数据:

高基数维度数据:个别是用户材料表、商品材料表相似的材料表。数据量可能是千万级或者上亿级别。

低基数维度数据:个别是配置表,比方枚举值对应的中文含意,或者日期维表。数据量可能是个位数或者几千几万。

2. 数仓建模办法

数仓建模在哪层建设呢?咱们以维度建模为例,建模是在数据源层的下一层进行建设 ,在上节的分层架构中, 就是在 DW 层进行数仓建模,所以DW 层是数仓建设的核心层

那数仓建模怎么建呢?其实数据仓库的建模办法有很多种,每一种建模办法代表了哲学上的一个观点 ,代表了一种演绎、概括世界的一种办法。常见的有 范式建模法、维度建模法、实体建模法 等,每种办法从实质上将是从不同的角度对待业务中的问题

1. 范式建模法(Third Normal Form,3NF)

范式建模法其实是咱们在构建数据模型罕用的一个办法,该办法的次要由 Inmon 所提倡,次要解决关系型数据库的数据存储,利用的一种技术层面上的办法。目前,咱们在关系型数据库中的建模办法,大部分采纳的是三范式建模法。

范式 是合乎某一种级别的关系模式的汇合。结构数据库必须遵循肯定的规定,而在关系型数据库中这种规定就是范式,这一过程也被称为规范化。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、Boyce-Codd 范式(BCNF)、第四范式(4NF)和第五范式(5NF)。

在数据仓库的模型设计中,个别采纳第三范式。一个合乎第三范式的关系必须具备以下三个条件 :

  • 每个属性值惟一,不具备多义性 ;
  • 每个非主属性必须齐全依赖于整个主键,而非主键的一部分 ;
  • 每个非主属性不能依赖于其余关系中的属性,因为这样的话,这种属性应该归到其余关系中去。

依据 Inmon 的观点,数据仓库模型的建设办法和业务零碎的企业数据模型相似。在业务零碎中,企业数据模型决定了数据的起源,而企业数据模型也分为两个档次,即主题域模型和逻辑模型。同样,主题域模型能够看成是业务模型的概念模型,而逻辑模型则是域模型在关系型数据库上的实例化。

2. 维度建模法(Dimensional Modeling)

维度模型是数据仓库畛域另一位巨匠 Ralph Kimall 所提倡,他的《数据仓库工具箱》是数据仓库工程畛域最风行的数仓建模经典。维度建模以剖析决策的需要登程构建模型,构建的数据模型为剖析需要服务,因而它重点解决用户如何更疾速实现剖析需要,同时还有较好的大规模简单查问的响应性能。

典型的代表是咱们比拟熟知的星形模型(Star-schema),以及在一些非凡场景下实用的雪花模型(Snow-schema)。

维度建模中比拟重要的概念就是 事实表(Fact table)和维度表(Dimension table)。其最简略的形容就是,依照事实表、维度表来构建数据仓库、数据集市。

3. 实体建模法(Entity Modeling)

实体建模法并不是数据仓库建模中常见的一个办法,它来源于哲学的一个流派。从哲学的意义上说,主观世界应该是能够细分的,主观世界应该能够分成由一个个实体,以及实体与实体之间的关系组成。那么咱们在数据仓库的建模过程中齐全能够引入这个形象的办法,将整个业务也能够划分成一个个的实体,而每个实体之间的关系,以及针对这些关系的阐明就是咱们数据建模须要做的工作。

尽管实体法粗看起来如同有一些形象,其实了解起来很容易。即咱们能够将任何一个业务过程划分成 3 个局部,实体,事件,阐明,如下图所示:

上图表述的是一个形象的含意,如果咱们形容一个简略的事实:“小明开车去学校上学”。以这个业务事实为例,咱们能够把“小明”,“学校”看成是一个实体,“上学”形容的是一个业务过程,咱们在这里能够形象为一个具体“事件”,而“开车去”则能够看成是事件“上学”的一个阐明。

3. 维度建模详解

目前在互联网公司最罕用的建模办法就是维度建模,咱们将重点解说!

维度建模是专门利用于剖析型数据库、数据仓库、数据集市建模的办法。数据集市能够了解为是一种 ” 小型数据仓库 ”。

咱们先不焦急开始维度建模,先来理解下 维度建模中表的类型 维度建模的模式 之后再开始建模,这样可能让咱们深刻理解!

1. 维度建模中表的类型

维度建模分为两种表:事实表和维度表:

  1. 事实表 :必然存在的一些数据,像采集的日志文件,订单表,都能够作为事实表。
    特色:是一堆主键的汇合,每个主键对应维度表中的一条记录,客观存在的,依据主题确定出须要应用的数据
  2. 维度表:维度就是所剖析的数据的一个量,维度表就是以适合的角度来创立的表,剖析问题的一个角度:工夫、地区、终端、用户等角度

1. 事实表

产生在事实世界中的操作型事件,其所产生的可度量数值,存储在事实表中。从最低的粒度级别来看,事实表行对应一个度量事件,反之亦然。

事实表示意对剖析主题的度量。比方一次购买行为咱们就能够了解为是一个事实。

图中的订单表就是一个事实表,你能够了解他就是在事实中产生的一次操作型事件,咱们每实现一个订单,就会在订单中减少一条记录。
事实表的特色:表里没有寄存理论的内容,他是一堆主键的汇合,这些 ID 别离能对应到维度表中的一条记录。事实表蕴含了与各维度表相关联的外键,可与维度表关联。事实表的度量通常是数值类型,且记录数会一直减少,表数据规模迅速增长。

明细表(宽表):

事实表的数据中,有些属性独特组成了一个字段(糅合在一起),比方年月日时分秒形成了工夫, 当须要依据某一属性进行分组统计的时候,须要截取拼接之类的操作,效率极低。
如:

local_time
2021-03-18 06:31:42

为了剖析不便,能够事实表中的一个字段切割提取多个属性进去形成新的字段,因为字段变多了,所以称为宽表,原来的成为窄表

将上述的 local_time 字段扩大为如下 6 个字段:

year month day hour m s
2021 03 18 06 31 42

又因为宽表的信息更加清晰明细,所以也能够称之为明细表。

事实表品种

事实表分为以下 6 类:

  1. 事务事实表
  2. 周期快照事实表
  3. 累积快照事实表
  4. 无事实的事实表
  5. 汇集事实表
  6. 合并事实表

简略解释下每种表的概念:

  • 事务事实表

表中的一行对应空间或工夫上某点的度量事件。就是一行数据中必须有度量字段,什么是度量,就是指标,比如说销售金额,销售数量等这些可加的或者半可加就是度量值。另一点就是事务事实表都蕴含一个与维度表关联的外键。并且度量值必须和事务粒度保持一致。

  • 周期快照事实表

顾名思义,周期事实表就是每行都带有工夫值字段,代表周期,通常工夫值都是规范周期,如某一天,某周,某月等。粒度是周期,而不是个体的事务,也就是说一个周期快照事实表中数据能够是多个事实,然而它们都属于某个周期内。

  • 累计快照事实表

周期快照事实表是单个周期内数据,而累计快照事实表是由多个周期数据组成,每行汇总了过程开始到完结之间的度量。每行数据相当于管道或工作流,有事件的终点,过程,起点,并且每个关键步骤都蕴含日期字段。如订单数据,累计快照事实表的一行就是一个订单,当订单产生时插入一行,当订单发生变化时,这行就被批改。

  • 无事实的事实表

咱们以上探讨的事实表度量都是数字化的,当然理论利用中绝大多数都是数字化的度量,然而也可能会有大量的没有数字化的值然而还很有价值的字段,无事实的事实表就是为这种数据筹备的,利用这种事实表能够剖析产生了什么。

  • 汇集事实表

汇集,就是对原子粒度的数据进行简略的聚合操作,目标就是为了进步查问性能。如咱们需要是查问全国所有门店的总销售额,咱们原子粒度的事实表中每行是每个分店每个商品的销售额,汇集事实表就能够先聚合每个分店的总销售额,这样汇总所有门店的销售额时计算的数据量就会小很多。

  • 合并事实表

这种事实表遵循一个准则,就是雷同粒度,数据能够来自多个过程,然而只有它们属于雷同粒度,就能够合并为一个事实表,这类事实表特地适宜常常须要独特剖析的多过程度量。

2.维度表

每个维度表都蕴含繁多的主键列。维度表的主键能够作为与之关联的任何事实表的外键,当然,维度表行的形容环境应与事实表行齐全对应。维度表通常比拟宽,是扁平型非标准表,蕴含大量的低粒度的文本属性。

维度示意你要对数据进行剖析时所用的一个量,比方你要剖析产品销售状况,你能够抉择按类别来进行剖析,或按区域来剖析。每个类别就形成一个维度。上图中的用户表、商家表、时间表这些都属于维度表,这些表都有一个惟一的主键,而后在表中寄存了具体的数据信息。

总的说来,在数据仓库中不须要严格遵守规范化设计准则。因为数据仓库的主导性能就是面向剖析,以查问为主,不波及数据更新操作。事实表的设计是以可能正确记录历史信息为准则,维度表的设计是以可能以适合的角度来聚合主题内容为准则

  • 维度表构造

维度表谨记一条准则,蕴含繁多主键列,但有时因业务简单,也可能呈现联结主键,请尽量避免,如果无奈防止,也要确保必须是繁多的,这很重要,如果维表主键不是繁多,和事实表关联时会呈现数据发散,导致最初后果可能呈现谬误。

维度表通常比拟宽,蕴含大量的低粒度的文本属性。

  • 跨表钻取

跨表钻取意思是当每个查问的行头都蕴含雷同的一致性属性时,使不同的查问可能针对两个或更多的事实表进行查问

钻取能够扭转维的档次,变换分析的粒度。它包含上钻 / 下钻:

上钻(roll-up):上卷是沿着维的档次向上汇集汇总数据。例如,对产品销售数据,沿着工夫维上卷,能够求出所有产品在所有地区每月(或季度或年或全副)的销售额。

下钻(drill-down):下钻是上钻的逆操作,它是沿着维的档次向下,查看更具体的数据。

  • 进化维度

进化维度就是将维度退回到事实表中。因为有时维度除了主键没有其余内容,尽管也是非法维度键,然而个别都会退回到事实表中,缩小关联次数,进步查问性能

  • 多层次维度

少数维度蕴含不止一个天然档次,如日期维度能够从天的档次到周到月到年的档次。所以在有些状况下,在同一维度中存在不同的档次。

  • 维度表空值属性

当给定维度行没有被全副填充时,或者当存在属性没有被利用到所有维度行时,将产生空值维度属性。上述两种状况,举荐采纳描述性字符串代替空值,如应用 unknown 或 not applicable 替换空值。

  • 日历日期维度

在日期维度表中,主键的设置不要应用程序生成的 id 来示意,能够应用更有意义的数据表示,比方将年月日合并起来示意,即 YYYYMMDD,或者更加具体的精度。

2. 维度建模三种模式

1. 星型模式

星形模式 (Star Schema) 是最罕用的维度建模形式。星型模式是以事实表为核心,所有的维度表间接连贯在事实表上,像星星一样
星形模式的维度建模由一个事实表和一组维表成,且具备以下特点:
a. 维表只和事实表关联,维表之间没有关联;
b. 每个维表主键为单列,且该主键搁置在事实表中,作为两边连贯的外键;
c. 以事实表为外围,维表围绕外围呈星形散布;

2. 雪花模式

雪花模式 (Snowflake Schema) 是对星形模式的扩大。雪花模式的维度表能够领有其余维度表的,尽管这种模型相比星型更标准一些,然而因为这种模型不太容易了解,保护老本比拟高,而且性能方面须要关联多层维表,性能也比星型模型要低。所以个别不是很罕用

3.星座模式

星座模式是星型模式延长而来,星型模式是基于一张事实表的,而 星座模式是基于多张事实表的,而且共享维度信息
后面介绍的两种维度建模办法都是多维表对应单事实表,但在很多时候维度空间内的事实表不止一个,而一个维表也可能被多个事实表用到。在 业务倒退前期,绝大部分维度建模都采纳的是星座模式

3. 维度建模过程

咱们晓得维度建模的表类型有事实表,维度表;模式有星形模型,雪花模型,星座模型这些概念了,然而理论业务中,给了咱们一堆数据,咱们怎么拿这些数据进行数仓建设呢,数仓工具箱作者依据本身 60 多年的理论业务教训,给咱们总结了如下四步,请务必记住!

数仓工具箱中的维度建模四步走

牢记 以上四步,不论什么业务,就依照这个步骤来,程序不要搞乱,因为这四步是环环相扣,步步相连。上面具体拆解下每个步骤怎么做

1、抉择业务过程
维度建模是紧贴业务的,所以必须以业务为根基进行建模,那么抉择业务过程,顾名思义就是在整个业务流程中选取咱们须要建模的业务,依据经营提供的需要及日后的易扩展性等进行抉择业务。比方商城,整个商城流程分为商家端,用户端,平台端,经营需要是总订单量,订单人数,及用户的购买状况等,咱们抉择业务过程就抉择用户端的数据,商家及平台端暂不思考。业务抉择十分重要,因为前面所有的步骤都是基于此业务数据开展的。

2、申明粒度
先举个例子:对于用户来说,一个用户有一个身份证号,一个户籍地址,多个手机号,多张银行卡,那么与用户粒度雷同的粒度属性有身份证粒度,户籍地址粒度,比用户粒度更细的粒度有手机号粒度,银行卡粒度,存在一对一的关系就是雷同粒度。为什么要提雷同粒度呢,因为维度建模中要求咱们,在 同一事实表 中,必须具备 雷同的粒度,同一事实表中不要混用多种不同的粒度,不同的粒度数据建设不同的事实表。并且从给定的业务过程获取数据时,强烈建议从关注原子粒度开始设计,也就是从最细粒度开始,因为原子粒度可能接受无奈预期的用户查问。然而上卷汇总粒度对查问性能的晋升很重要的,所以对于有明确需要的数据,咱们建设针对需要的上卷汇总粒度,对需要不明朗的数据咱们建设原子粒度。

3、确认维度
维度表是作为业务剖析的入口和描述性标识,所以也被称为数据仓库的“灵魂”。在一堆的数据中怎么确认哪些是维度属性呢,如果该列是对具体值的形容,是一个文本或常量,某一束缚和行标识的参与者,此时该属性往往是维度属性,数仓工具箱中通知咱们 牢牢把握事实表的粒度,就能将所有可能存在的维度辨别开 ,并且要 确保维度表中不能呈现反复数据,应使维度主键惟一

4、确认事实
事实表是用来度量的,基本上都以数量值示意,事实表中的每行对应一个度量,每行中的数据是一个特定级别的细节数据,称为粒度。维度建模的外围准则之一 是同一事实表中的所有度量必须具备雷同的粒度 。这样能确保不会呈现反复计算度量的问题。有时候往往不能确定该列数据是事实属性还是维度属性。记住 最实用的事实就是数值类型和可加类事实。所以能够通过剖析该列是否是一种蕴含多个值并作为计算的参与者的度量,这种状况下该列往往是事实。

三、离线数仓建设实战

技术是为业务服务的,业务是为公司发明价值的,来到业务的技术是无意义的

1. 业务介绍

须要针对不同需要的用户开发不同的产品,所以公司外部有很多条业务线,然而对于数据部门来说,所有业务线的数据都是数据源。对数据的划分不只是依据业务进行,而是联合数据的属性。

2. 晚期布局

之前开发是不同业务线对应不同的数据团队,每个数据团队互不烦扰,这种模式比较简单,只针对本人的业务线进行数仓建设及报表开发即可。

然而随着业务的倒退,频繁迭代及跨部门的垂直业务单元越来越多,业务之间的呈现耦合状况,这时再采纳这种烟囱式开发就呈现了问题:

例如权限问题,公司对数据管理比拟严格,不同的数据开发组没有权限共享数据,须要其余业务线的数据权限须要上报审批,比拟耽误时间;

还有反复开发问题,不同业务线会呈现雷同的报表需要,如果每个业务方都开发各自的报表,太浪费资源。

所以对于数据开发而言,须要对各个业务线的数据进行对立治理,所以就有了数据中台的呈现。

3. 数据中台

我认为数据中台是依据每个公司具体的业务需要而搭建的,不同的业务,对中台的了解有所不同。

公司外部开发的麻利数据中台,次要从数据技术和计算能力的复用,到数据资产和数据服务的复用,数据中台以更大价值带宽,快准精让数据间接赋能业务。提供一个统一化的治理,突破数据孤岛,追溯数据血统,实现自助化及高复用度。

如下所示:

以上解释比拟形象,咱们以理论我的项目开发来看下数据中台的便利性。

比方咱们之前做报表开发流程,首先是要数据采集,不同的数据源通过 sqoop 等工具采集到大数据平台,而后进行数仓搭建,最初产出报表数据,放到可视化零碎展现,最终把整个流程写成脚本放到调度平台进行自动化执行。

而有了数据中台之后就不须要那么繁琐,间接进行数仓搭建,产生报表即可,无需将精力过多放在数据源、可视化展现及调度。并且能够直观的查看数据血缘关系,计算表之间血统。像上面图中,表之间的依赖关系很明确:

另一点,数据中台的异构数据系统能够非常简单的进行关联查问,比方 hive 的表关联 mysql 的表。
可通明屏蔽异构数据系统异构交互方式,轻松实现跨异构数据系统通明混算。

异构数据系统原理是数据中台提供虚构表到物理表之间的映射, 终端用户无需关怀数据的物理寄存地位和底层数据源的个性,可间接操作数据,体验相似操作一个虚构数据库

数据中台额定集成可视化展现,提供一站式数据可视化解决方案,反对 JDBC 数据源和 CSV 文件上传,反对基于数据模型拖拽智能生成可视化组件,大屏展现自适应不同大小屏幕。

调度零碎是公司外部自写集成到数据中台的,在编写完 sql 语句之后能够间接进行调度。

4. 数仓建设

到这才真正到数仓建设,为什么后面我要占那么大篇幅去介绍公司业务及所应用的数据中台零碎,因为上面的数仓建设是依据公司的业务倒退及现有的数据中台进行,数仓的建设离不开公司的业务。

数仓建设核心思想:从设计、开发、部署和应用层面,防止反复建设和指标冗余建设,从而保障数据口径的标准和对立,最终实现数据资产全链路关联、提供规范数据输入以及建设对立的数据公共层。
有了核心思想,那怎么开始数仓建设,有句话说数仓建设者即是技术专家,也是大半个业务专家,所以采纳的形式就是需要推动数据建设,并且因为数据中台,所以各业务知识体系比拟集中,各业务数据不再扩散,放慢了数仓建设速度。
数仓建设次要从两个方面进行,模型和标准,所有业务进行统一化

  • 模型

所有业务采纳对立的模型体系,从而升高研发老本,加强指标复用,并且能保证数据口径的对立

  • 模型分层

联合公司业务,前期新增需要较多,所以分层不宜过多,并且须要清晰明确各层职责,要保证数据层的稳固又要屏蔽对上游影响,所以采纳如下分层构造:

  • 数据流向

遵循模型开发时分层构造,数据从 ods -> dw -> dm ->app 这样正向流动,能够避免因数据援用不标准而造成数据链路凌乱及 SLA 时效难保障等问题,同时保障血缘关系简洁化,可能轻易追踪数据流向。
在开发时应防止以下状况呈现:

  1. 数据援用链路不正确,如 ods -> dm ->app,呈现这种状况阐明明细层没有齐全笼罩数据;如 ods -> dw -> app,阐明轻度汇总层主题划分未笼罩全。缩小跨层援用,能力进步两头表的复用度。现实的数仓模型设计该当具备:数据模型可复⽤,欠缺且标准
  2. 尽量避免一层的表生成以后层的表,如 dw 层表生成 dw 层表,这样会影响 ETL 效率。
  3. 禁止呈现反向依赖,如 dw 表依赖于 dm 表。
  • 标准
  • 表命名标准

    1. 对于 ods、dm、app 层表名:类型 \_主题 \_表含意,如:dm\_xxsh\_user
    2. 对于 dw 层表名:类型 \_主题 \_维度 \_表含意,如:dw\_xxsh\_fact\_users(事实表)、dw\_xxsh\_dim\_city(维度表)
  • 字段命名标准
    构建词根,词根是维度和指标治理的根底,划分为一般词根与专有词根

    1. 一般词根:形容事物的最小单元体,如:sex- 性别。
    2. 专有词根:具备行业专属或公司外部规定的形容体,如:xxsh- 公司外部对某个产品的称说。
  • 脚本命名标准
    脚本名称:脚本类型. 脚本功能.[库名]. 脚本名称,如 hive.hive.dm.dm\_xxsh\_users
    脚本类型次要分为以下三类:

    1. 惯例 Hive sql:hive
    2. 自定义 shell 脚本:sh
    3. 自定义 Python 脚本:python
  • 脚本内容标准

    # 变量的定义要合乎 python 的语法要求
    #指定工作负责人
    owner = "zhangsan@xxx.com"
    #脚本寄存目录 /opt/xxx
    #脚本名称 hive.hive.dm.dm_xxsh_users
    #source 用来标识上游依赖表,一个工作如果有多个上游表,都须要写进去
    #(xxx_name 是须要改变的,其余不须要改)
    source = {
          "table_name": {
          "db": "db_name",
          "table": "table_name"
          }
    }
    #如 source,然而每个工作 target 只有一张表
    target = {
          "db_table": {
                  "host": "hive",
                  "db": "db_name",
                  "table": "table_name"
          }
    }
    #变量列表
    #$now
    #$now.date 罕用,格局示例:2020-12-11
    
     
    task = '''写 sql 代码'''

    5. 数据层具体实现

应用四张图阐明每层的具体实现

  • 数据源层 ODS

数据源层次要将各个业务数据导入到大数据平台,作为业务数据的快照存储。

  • 数据明细层 DW

事实表中的每行对应一个度量,每行中的数据是一个特定级别的细节数据,称为粒度。维度建模的外围准则之一是 同一事实表中的所有度量必须具备雷同的粒度。这样能确保不会呈现反复计算度量的问题。

维度表个别都是繁多主键,多数是联结主键,留神维度表不要呈现反复数据,否则和事实表关联会呈现 数据发散 问题。

有时候往往不能确定该列数据是事实属性还是维度属性。记住 最实用的事实就是数值类型和可加类事实。所以能够通过剖析该列是否是一种蕴含多个值并作为计算的参与者的度量,这种状况下该列往往是事实;如果该列是对具体值的形容,是一个文本或常量,某一束缚和行标识的参与者,此时该属性往往是维度属性。然而还是要联合业务进行最终判断是维度还是事实。

  • 数据轻度汇总层 DM

此层命名为轻汇总层,就代表这一层曾经开始对数据进行汇总,然而不是齐全汇总,只是对雷同粒度的数据进行关联汇总,不同粒度然而有关系的数据也可进行汇总,此时须要将粒度通过聚合等操作进行对立。

  • 数据应用层 APP

数据应用层的表就是提供给用户应用的,数仓建设到此就靠近序幕了,接下来就依据不同的需要进行不同的取数,如间接进行报表展现,或提供给数据分析的共事所需的数据,或其余的业务撑持。

6. 总结

一张图总结下数据仓库的构建整体流程

7. 理论生产中注意事项

生产环境中操作不能像咱们本人测试时那样随便,一不小心都可能造成生产事变。所以每步操作都要非常小心,需全神贯注,管好大脑管住右手。

仅列出以下但不限于以下的注意事项:

  • 请勿操作本人治理及受权表之外的其它库表;
  • 未经受权,请勿操作生产环境中其他人的脚本及文件;
  • 在批改生产环境脚本前,请务必自行备份到本地;
  • 请确认本人的批改操作能迅速回滚;
  • 生产环境中表名及字段等所有命名请遵循命名规定。

举荐浏览:

联合公司业务剖析离线数仓建设

数仓建设中最罕用模型 –Kimball 维度建模详解

四、实时计算

实时计算个别都是针对海量数据进行的,并且要求为秒级。因为大数据衰亡之初,Hadoop 并没有给出实时计算解决方案,随后 Storm,SparkStreaming,Flink 等实时计算框架应运而生,而 Kafka,ES 的衰亡使得实时计算畛域的技术越来越欠缺,而随着物联网,机器学习等技术的推广,实时流式计算将在这些畛域失去充沛的利用。

实时计算的三个特色

  1. 有限数据:有限数据指的是一种一直增长的,基本上有限的数据集。这些通常被称为“流数据”,而与之绝对的是无限的数据集。
  2. 无界数据处理:一种继续的数据处理模式, 可能通过解决引擎反复的去解决下面的有限数据,是可能冲破无限数据处理引擎的瓶颈的。
  3. 低提早:提早是多少并没有明确的定义。但咱们都晓得数据的价值将随着工夫的流逝升高,时效性将是须要继续解决的问题。

当初大数据利用比拟火爆的畛域,比方举荐零碎在实际之初受技术所限,可能要一分钟,一小时,甚至更久对用户进行举荐,这远远不能满足需要,咱们须要更快的实现对数据的解决,而不是进行离线的批处理。

1. 实时计算利用场景

随着实时技术倒退趋于成熟,实时计算利用越来越宽泛,以下仅列举常见的几种实时计算的利用场景:

1. 实时智能举荐

智能举荐会依据用户历史的购买或浏览行为,通过举荐算法训练模型,预测用户将来可能会购买的物品或青睐的资讯。对集体来说,举荐零碎起着信息过滤的作用,对 Web/App 服务端来说,举荐零碎起着满足用户个性化需要,晋升用户满意度的作用。举荐零碎自身也在飞速发展,除了算法越来越欠缺,对时延的要求也越来越刻薄和实时化。利用 Flink 流计算帮忙用户构建更加实时的智能举荐零碎,对用户行为指标进行实时计算,对模型进行实时更新,对用户指标进行实时预测,并将预测的信息推送给 Web/App 端,帮忙用户获取想要的商品信息,另一方面也帮忙企业晋升销售额,发明更大的商业价值。

2. 实时欺诈检测

在金融畛域的业务中,经常呈现各种类型的欺诈行为,例如信用卡欺诈,信贷申请欺诈等,而如何保障用户和公司的资金平安,是近年来许多金融公司及银行独特面对的挑战。随着不法分子欺诈伎俩的一直降级,传统的反欺诈伎俩曾经不足以解决目前所面临的问题。以往可能须要几个小时能力通过交易数据计算出用户的行为指标,而后通过规定判断出具备欺诈行为嫌疑的用户,再进行案件考察解决,在这种状况下资金可能早已被不法分子转移,从而给企业和用户造成大量的经济损失。而使用 Flink 流式计算技术可能在毫秒内就实现对欺诈行为判断指标的计算,而后实时对交易流水进行实时拦挡,防止因为解决不及时而导致的经济损失。

3. 舆情剖析

有的客户须要做舆情剖析,要求所有数据寄存若干年,舆情数据每日数据量可能超百万,年数据量可达到几十亿的数据。而且爬虫爬过去的数据是舆情,通过大数据技术进行分词之后失去的可能是大段的网友评论,客户往往要求对舆情进行查问,做全文本搜寻,并要求响应工夫管制在秒级。爬虫将数据爬到大数据平台的 Kafka 里,在外面做 Flink 流解决,去重去噪做语音剖析,写到 ElasticSearch 里。大数据的一个特点是多数据源,大数据平台能依据不同的场景抉择不同的数据源。

4. 简单事件处理

对于简单事件处理,比拟常见的集中于工业畛域,例如对车载传感器,机械设备等实时故障检测,这些业务类型通常数据量都十分大,且对数据处理的时效性要求十分高。通过利用 Flink 提供的 CEP 进行工夫模式的抽取,同时利用 Flink 的 Sql 进行事件数据的转换,在流式零碎中构建施行规定引擎,一旦事件触发报警规定,便立刻将告警后果告诉至上游告诉零碎,从而实现对设施故障疾速预警检测,车辆状态监控等目标。

5. 实时机器学习

实时机器学习是一个更宽泛的概念,传统动态的机器学习次要侧重于动态的模型和历史数据进行训练并提供预测。很多时候用户的短期行为,对模型有修改作用,或者说是对业务判断有预测作用。对系统来说,须要采集用户最近的行为并进行特色工程,而后给到实时机器学习零碎进行机器学习。如果动静地施行新规定,或是推出新广告,就会有很大的参考价值。

2. 实时计算总览

咱们先来看一张大数据平台的实时架构图:

  • 数据同步:

在下面这张架构图中,数据从 Web 平台中产生,通过数据同步零碎导入到大数据平台,因为数据源不同,这里的数据同步零碎实际上是多个相干零碎的组合。数据库同步通常用 Sqoop,日志同步能够抉择 Flume 等,不同的数据源产生的数据品质可能差异很大,数据库中的格式化数据间接导入大数据系统即可,而日志和爬虫产生的数据就须要进行大量的荡涤、转化解决能力无效应用。

  • 数据存储:

该层对原始数据、荡涤关联后的明细数据进行存储,基于对立的实时数据模型分层理念,将不同利用场景的数据别离存储在 Kafka、HDFS、Kudu、Clickhouse、Hbase 等存储中。

  • 数据计算:

计算层次要应用 Flink、Spark、Presto 以及 ClickHouse 自带的计算能力等四种计算引擎,Flink 计算引擎次要用于实时数据同步、流式 ETL、要害零碎秒级实时指标计算场景,Spark SQL 次要用于简单多维分析的准实时指标计算需要场景,Presto 和 ClickHouse 次要满足多维自助剖析、对查问响应工夫要求不太高的场景。

  • 实时利用:

以对立查问服务对各个业务线数据场景进行反对,业务次要包含实时大屏、实时数据产品、实时 OLAP、实时特色等。

当然一个好的大数据平台不能短少元数据管理及数据治理

1. 元数据及指标治理:次要对实时的 Kafka 表、Kudu 表、Clickhouse 表、Hive 表等进行对立治理,以数仓模型中表的命名形式标准表的命名,明确每张表的字段含意、应用方,指标治理则是尽量通过指标管理系统将所有的实时指标对立治理起来,明确计算口径,提供给不同的业务方应用;

2. 数据品质及血统剖析:数据品质分为平台监控和数据监控两个局部,血统剖析则次要是对实时数据依赖关系、实时工作的依赖关系进行剖析。

以上架构只是大数据平台通用的数据模型,如果要具体的建设,须要思考以下状况,业务需要须要实时还是准实时即可,数据时效性是秒级还是分钟级等。

  • 调度开销 方面,准实时数据是批处理过程,因而依然须要调度零碎反对,调度频率较高,而实时数据却没有调度开销;
  • 业务灵活性 方面,因为准实时数据是基于 ETL 或 OLAP 引擎实现,灵活性优于基于流计算的形式;
  • 对数据晚到的容忍度 方面,因为准实时数据能够基于一个周期内的数据进行全量计算,因而对于数据晚到的容忍度也是比拟高的,而实时数据应用的是增量计算,对于数据晚到的容忍度更低一些;
  • 实用场景 方面,准实时数据次要用于有实时性要求但不太高、波及多表关联和业务变更频繁的场景,如交易类型的实时剖析,实时数据则更实用于实时性要求高、数据量大的场景,如实时特色、流量类型实时剖析等场景。

3. 实时架构

在某些场景中,数据的价值随着工夫的推移而逐步缩小。所以在传统大数据离线数仓的根底上,逐步对数据的实时性提出了更高的要求。

于是随之诞生了大数据实时数仓,并且衍生出了两种技术架构 Lambda 和 Kappa。

1. Lambda 架构

先来看下 Lambda 架构图:

数据从底层的数据源开始,通过 Kafka、Flume 等数据组件进行收集,而后分成两条线进行计算:

  • 一条线是进入流式计算平台(例如 Storm、Flink 或者 SparkStreaming),去计算实时的一些指标;
  • 另一条线进入批量数据处理离线计算平台(例如 Mapreduce、Hive,Spark SQL),去计算 T + 1 的相干业务指标,这些指标须要隔日能力看见。

为什么 Lambda 架构要分成两条线计算?

如果整个零碎只有一个批处理层,会导致用户必须期待很久能力获取计算结果,个别有几个小时的提早。电商数据分析部门只能查看前一天的统计分析后果,无奈获取以后的后果,这对于实时决策来说有一个微小的工夫鸿沟,很可能导致管理者错过最佳决策机会。

Lambda 架构属于较早的一种架构形式,晚期的流解决不如当初这样成熟,在准确性、扩展性和容错性上,流解决层无奈间接取代批处理层,只能给用户提供一个近似后果,还不能为用户提供一个统一精确的后果。因而 Lambda 架构中,呈现了批处理和流解决并存的景象。

在 Lambda 架构中,每层都有本人所肩负的工作。

1. 批处理层存储管理主数据集(不可变的数据集)和事后批处理计算好的视图:

批处理层应用可解决大量数据的分布式解决零碎事后计算结果。它通过解决所有的已有历史数据来实现数据的准确性。这意味着它是基于残缺的数据集来从新计算的,可能修复任何谬误,而后更新现有的数据视图。输入通常存储在只读数据库中,更新则齐全取代现有的事后计算好的视图。

2. 流解决层会实时处理新来的大数据:

流解决层通过提供最新数据的实时视图来最小化提早。流解决层所生成的数据视图可能不如批处理层最终生成的视图那样精确或残缺,但它们简直在收到数据后立刻可用。而当同样的数据在批处理层解决实现后,在速度层的数据就能够被代替掉了。

那 Lambda 架构有没有毛病呢?

Lambda 架构经验多年的倒退,其长处是稳固,对于实时计算局部的计算成本可控,批量解决能够用早晨的工夫来整体批量计算,这样把实时计算和离线计算顶峰离开,这种架构撑持了数据行业的晚期倒退,然而它也有一些致命毛病,并在大数据 3.0 时代越来越不适应数据分析业务的需要。毛病如下:

  • 应用两套大数据处理引擎:保护两个简单的分布式系统,老本十分高。
  • 批量计算在计算窗口内无奈实现:在 IOT 时代,数据量级越来越大,常常发现夜间只有 4、5 个小时的工夫窗口,曾经无奈实现白天 20 多个小时累计的数据,保障早上下班前准时出数据已成为每个大数据团队头疼的问题。
  • 数据源变动都要从新开发,开发周期长:每次数据源的格局变动,业务的逻辑变动都须要针对 ETL 和 Streaming 做开发批改,整体开发周期很长,业务反馈不够迅速。

导致 Lambda 架构的毛病根本原因是要同时保护两套零碎架构:批处理层和速度层。咱们曾经晓得,在架构中退出批处理层是因为从批处理层失去的后果具备高准确性,而退出速度层是因为它在解决大规模数据时具备低延时性。

那咱们能不能改良其中某一层的架构,让它具备另外一层架构的个性呢?

例如,改良批处理层的零碎让它具备更低的延时性,又或者是改良速度层的零碎,让它产生的数据视图更具准确性和更加靠近历史数据呢?

另外一种在大规模数据处理中罕用的架构——Kappa 架构,便是在这样的思考下诞生的。

2. Kappa 架构

Kafka 的创始人 Jay Kreps 认为在很多场景下,保护一套 Lambda 架构的大数据处理平台耗时耗力,于是提出在某些场景下,没有必要保护一个批处理层,间接应用一个流解决层即可满足需要,即下图所示的 Kappa 架构:

这种架构只关注流式计算,数据以流的形式被采集过去,实时计算引擎将计算结果放入数据服务层以供查问。能够认为 Kappa 架构是 Lambda 架构的一个简化版本,只是去除掉了 Lambda 架构中的离线批处理局部

Kappa 架构的衰亡次要有两个起因

  • Kafka 不仅起到音讯队列的作用,也能够保留更长时间的历史数据,以代替 Lambda 架构中批处理层数据仓库局部。流解决引擎以一个更早的工夫作为终点开始生产,起到了批处理的作用。
  • Flink 流解决引擎解决了事件乱序下计算结果的准确性问题。

Kappa 架构绝对更简略,实时性更好,所需的计算资源远小于 Lambda 架构,随着实时处理的需要在一直增长,更多的企业开始应用 Kappa 架构。但这不意味着 kappa 架构可能取代 Lambda 架构

Lambda 和 kappa 架构都有各自的实用畛域;例如流解决与批处理剖析流程比拟对立,且容许肯定的容错,用 Kappa 比拟适合,大量要害指标(例如交易金额、业绩统计等)应用 Lambda 架构进行批量计算,减少一次校对过程。

还有一些比较复杂的场景,批处理与流解决产生不同的后果(应用不同的机器学习模型,专家系统,或者实时计算难以解决的简单计算),可能更适宜 Lambda 架构。

4. 实时数仓解决方案

实时数仓分层架构为了防止面向需要响应的烟囱式构建,实时数仓也引入了相似于离线数仓的分层理念,次要是为了进步模型的复用率,同时也要思考易用性、一致性以及计算成本。

当然实时数仓的分层架构在设计上并不会像离线数仓那么简单,防止数据在流转过程中造成的不必要的延时响应

实时数仓分层架构图:

  1. ODS 层:以 Kafka 为撑持,将所有须要实时处理的相干数据放到 Kafka 队列中来实现贴源数据层;
  2. DWD 层:实时计算订阅业务数据音讯队列,而后通过数据荡涤、多数据源 join、流式数据与离线维度信息等的组合,将一些雷同粒度的业务零碎、维表中的维度属性全副关联到一起,减少数据易用性和复用性,失去最终的实时明细数据;
  3. DIM 层:寄存用于关联查问的维度信息,能够依据数据现状来抉择存储介质,例如应用 HBase 或者 Mysql
  4. DWS 层:轻度汇总层是为了便于面向 AdHoc 查问或者 Olap 剖析构建的轻度汇总后果汇合,适宜数据维度、指标信息比拟多的状况,为了不便依据自定义条件的疾速筛选和指标聚合,举荐应用 MPP 类型数据库进行存储,此层可视场景状况决定是否构建;
  5. APP 层:面向实时数据场景需要构建的高度汇总层,能够依据不同的数据利用场景决定应用存储介质或者引擎;例如面向业务历史明细、BI 反对等 Olap 剖析场景,能够应用 Druid、Greenplum,面向实时监控大屏、高并发汇总指标等需要,能够应用 KV 模式的 HBase;数据量较小的时候,也能够应用 Mysql 来进行存储。

这里要留神下,其实 APP 层曾经脱离了数仓,这里尽管作为了数仓的独立分层,然而理论 APP 层的数据曾经散布存储在各种介质中用于应用。

基于 Flink 构建的实时数仓

随着业务场景的丰盛,更多的实时需要不断涌现,在谋求实时工作高吞吐低提早的同时,对计算过程中间状态治理,灵便工夫窗口反对,以及 exactly once 语义保障的诉求也越来越多。

为什么抉择 Flink 实时计算平台?之所以抉择用 Flink 代替原有 Storm、SparkStreaming 是基于以下起因思考的,这也是实时数仓关注的外围问题:

  1. 高吞吐、低延时;
  2. 端到端的 Exactly-once,保障了数据的准确性;
  3. 可容错的状态治理,实时数仓外面会进行很多的聚合计算,这些都须要对于状态进行拜访和治理;
  4. 丰盛的 API,对 Streaming/Table/SQL 反对良好,反对 UDF、流式 join、工夫窗口等高级用法;
  5. 欠缺的生态体系,实时数仓的构建会波及多种存储,Flink 在这方面的反对也比较完善。

基于 Flink 的实时数仓数据流转过程:

数据在实时数仓中的流转过程,理论和离线数仓十分类似,只是由 Flink 代替 Hive 作为了计算引擎,把存储由 HDFS 更换成了 Kafka,然而模型的构建思路与流转过程并没有发生变化。

五、实时数仓建设外围

1. 实时计算初期

尽管实时计算在最近几年才火起来,然而在晚期也有局部公司有实时计算的需要,然而数据量比拟少,所以在实时方面造成不了残缺的体系,根本所有的开发都是具体问题具体分析,来一个需要做一个,根本不思考它们之间的关系,开发模式如下:

如上图所示,拿到数据源后,会通过数据荡涤,扩维,通过 Flink 进行业务逻辑解决,最初间接进行业务输入。把这个环节拆开来看,数据源端会反复援用雷同的数据源,前面进行荡涤、过滤、扩维等操作,都要反复做一遍,惟一不同的是业务的代码逻辑是不一样的。

随着产品和业务人员对实时数据需要的一直增多,这种开发模式呈现的问题越来越多:

  1. 数据指标越来越多,“烟囱式”的开发导致代码耦合问题重大。
  2. 需要越来越多,有的须要明细数据,有的须要 OLAP 剖析。繁多的开发模式难以应酬多种需要。
  3. 每个需要都要申请资源,导致资源老本急速收缩,资源不能粗放无效利用。
  4. 短少欠缺的监控零碎,无奈在对业务产生影响之前发现并修复问题。

大家看实时数仓的倒退和呈现的问题,和离线数仓十分相似,前期数据量大了之后产生了各种问题,离线数仓过后是怎么解决的?离线数仓通过分层架构使数据解耦,多个业务能够共用数据,实时数仓是否也能够用分层架构呢?当然是能够的,然而细节上和离线的分层还是有一些不同,稍后会讲到。

2. 实时数仓建设

从方法论来讲,实时和离线是十分类似的,离线数仓晚期的时候也是具体问题具体分析,当数据规模涨到一定量的时候才会思考如何治理。分层是一种十分无效的数据治理形式,所以在实时数仓如何进行治理的问题上,首先思考的也是分层的解决逻辑。

实时数仓的架构如下图:

从上图中咱们具体分析下每层的作用:

  • 数据源:在数据源的层面,离线和实时在数据源是统一的,次要分为日志类和业务类,日志类又包含用户日志,埋点日志以及服务器日志等。
  • 实时明细层:在明细层,为了解决反复建设的问题,要进行对立构建,利用离线数仓的模式,建设对立的根底明细数据层,依照主题进行治理,明细层的目标是给上游提供间接可用的数据,因而要对根底层进行对立的加工,比方荡涤、过滤、扩维等。
  • 汇总层:汇总层通过 Flink 的简洁算子间接能够算出后果,并且造成汇总指标池,所有的指标都对立在汇总层加工,所有人依照对立的标准治理建设,造成可复用的汇总后果。

咱们能够看出,实时数仓和离线数仓的分层十分相似,比方 数据源层,明细层,汇总层,乃至应用层,他们命名的模式可能都是一样的。但认真比拟不难发现,两者有很多区别:

  • 与离线数仓相比,实时数仓的档次更少一些:

    • 从目前建设离线数仓的教训来看,数仓的数据明细层内容会十分丰盛,解决明细数据外个别还会蕴含轻度汇总层的概念,另外离线数仓中应用层数据在数仓外部,但实时数仓中,app 应用层数据曾经落入利用零碎的存储介质中,能够把该层与数仓的表拆散
    • 应用层少建设的益处:实时处理数据的时候,每建一个档次,数据必然会产生肯定的提早
    • 汇总层少建的益处:在汇总统计的时候,往往为了容忍一部分数据的提早,可能会人为的制作一些提早来保证数据的精确。举例,在统计跨天相干的订单事件中的数据时,可能会等到 00:00:05 或者 00:00:10 再统计,确保 00:00 前的数据曾经全副承受到位了,再进行统计。所以,汇总层的档次太多的话,就会更大的减轻人为造成的数据提早。
  • 与离线数仓相比,实时数仓的数据源存储不同:

    • 在建设离线数仓的时候,根本整个离线数仓都是建设在 Hive 表之上 。然而,在建设实时数仓的时候,同一份表,会应用不同的形式进行存储。比方常见的状况下, 明细数据或者汇总数据都会存在 Kafka 外面,然而像城市、渠道等维度信息须要借助 Hbase,MySQL 或者其余 KV 存储等数据库来进行存储

3. Lambda 架构的实时数仓

Lambda 和 Kappa 架构的概念已在前文中解释,不理解的小伙伴可点击链接:一文读懂大数据实时计算

下图是基于 Flink 和 Kafka 的 Lambda 架构的具体实际,下层是实时计算,上层是离线计算,横向是按计算引擎来分,纵向是按实时数仓来辨别:

Lambda 架构是比拟经典的架构,以前实时的场景不是很多,以离线为主,当附加了实时场景后,因为离线和实时的时效性不同,导致技术生态是不一样的。Lambda 架构相当于附加了一条实时生产链路,在利用层面进行一个整合,双路生产,各自独立。这在业务利用中也是牵强附会采纳的一种形式。

双路生产会存在一些问题,比方加工逻辑 double,开发运维也会 double,资源同样会变成两个资源链路。因为存在以上问题,所以又演进了一个 Kappa 架构。

4. Kappa 架构的实时数仓

Kappa 架构相当于去掉了离线计算局部的 Lambda 架构,具体如下图所示:

Kappa 架构从架构设计来讲比较简单,生产对立,一套逻辑同时生产离线和实时。然而在理论利用场景有比拟大的局限性,因为实时数据的同一份表,会应用不同的形式进行存储,这就导致关联时须要跨数据源,操作数据有很大局限性,所以在业内间接用 Kappa 架构生产落地的案例不多见,且场景比拟繁多。

对于 Kappa 架构,相熟实时数仓生产的同学,可能会有一个疑难。因为咱们常常会面临业务变更,所以很多业务逻辑是须要去迭代的。之前产出的一些数据,如果口径变更了,就须要重算,甚至重刷历史数据。对于实时数仓来说,怎么去解决数据重算问题?

Kappa 架构在这一块的思路是:首先要筹备好一个可能存储历史数据的音讯队列,比方 Kafka,并且这个音讯队列是能够反对你从某个历史的节点从新开始生产的。接着须要新起一个工作,从原来比拟早的一个工夫节点去生产 Kafka 上的数据,而后当这个新的工作运行的进度曾经可能和当初的正在跑的工作齐平的时候,你就能够把当初工作的上游切换到新的工作下面,旧的工作就能够停掉,并且原来产出的后果表也能够被删掉。

5. 流批联合的实时数仓

随着实时 OLAP 技术的倒退,目前开源的 OLAP 引擎在性能,易用等方面有了很大的晋升,如 Doris、Presto 等,加上数据湖技术的迅速倒退,使得流批联合的形式变得简略。

如下图是流批联合的实时数仓:

数据从日志对立采集到音讯队列,再到实时数仓,作为根底数据流的建设是对立的。之后对于日志类实时特色,实时大屏类利用走实时流计算。对于 Binlog 类业务剖析走实时 OLAP 批处理。

咱们看到流批联合的形式与下面几种架构的存储形式产生了变动,由 Kafka 换成了 Iceberg,Iceberg 是介于下层计算引擎和底层存储格局之间的一个中间层,咱们能够把它定义成一种“数据组织格局”,底层存储还是 HDFS,那么为什么加了中间层,就对流批联合解决的比拟好了呢?Iceberg 的 ACID 能力能够简化整个流水线的设计,升高整个流水线的提早,并且所具备的批改、删除能力可能无效地升高开销,晋升效率。Iceberg 能够无效反对批处理的高吞吐数据扫描和流计算按分区粒度并发实时处理。

六、基于 Flink SQL 从 0 到 1 构建一个实时数仓

注:本大节内容来自公众号大数据技术与数仓!

实时数仓次要解决传统数仓数据时效性低的问题,实时数仓通常会用在实时的 OLAP 剖析,实时大屏展现,实时监控报警各个场景。尽管对于实时数仓架构及技术选型与传统的离线数仓会存在差别,然而对于数仓建设的根本方法论是统一的。接下来次要介绍 Flink SQL 从 0 到 1 搭建一个实时数仓的 demo,波及到数据采集、存储、计算、可视化整个流程。

1. 案例简介

本文以电商业务为例,展现实时数仓的数据处理流程。另外,本文旨在阐明实时数仓的构建流程,所以不会波及简单的数据计算。为了保障案例的可操作性和完整性,本文会给出具体的操作步骤。为了不便演示,本文的所有操作都是在 Flink SQL Cli 中实现。

2. 架构设计

具体的架构设计如图所示:首先通过 canal 解析 MySQL 的 binlog 日志,将数据存储在 Kafka 中。而后应用 Flink SQL 对原始数据进行荡涤关联,并将解决之后的明细宽表写入 Kafka 中。维表数据存储在 MySQL 中,通过 Flink SQL 对明细宽表与维表进行 join,将聚合后的数据写入 MySQL,最初通过 FineBI 进行可视化展现。

3. 业务数据筹备

1. 订单表(order_info)

CREATE TABLE `order_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `consignee` varchar(100) DEFAULT NULL COMMENT '收货人',
  `consignee_tel` varchar(20) DEFAULT NULL COMMENT '收件人电话',
  `total_amount` decimal(10,2) DEFAULT NULL COMMENT '总金额',
  `order_status` varchar(20) DEFAULT NULL COMMENT '订单状态',
  `user_id` bigint(20) DEFAULT NULL COMMENT '用户 id',
  `payment_way` varchar(20) DEFAULT NULL COMMENT '付款形式',
  `delivery_address` varchar(1000) DEFAULT NULL COMMENT '送货地址',
  `order_comment` varchar(200) DEFAULT NULL COMMENT '订单备注',
  `out_trade_no` varchar(50) DEFAULT NULL COMMENT '订单交易编号(第三方领取用)',
  `trade_body` varchar(200) DEFAULT NULL COMMENT '订单形容(第三方领取用)',
  `create_time` datetime DEFAULT NULL COMMENT '创立工夫',
  `operate_time` datetime DEFAULT NULL COMMENT '操作工夫',
  `expire_time` datetime DEFAULT NULL COMMENT '生效工夫',
  `tracking_no` varchar(100) DEFAULT NULL COMMENT '物流单编号',
  `parent_order_id` bigint(20) DEFAULT NULL COMMENT '父订单编号',
  `img_url` varchar(200) DEFAULT NULL COMMENT '图片门路',
  `province_id` int(20) DEFAULT NULL COMMENT '地区',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='订单表';

2. 订单详情表(order_detail)

CREATE TABLE `order_detail` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `order_id` bigint(20) DEFAULT NULL COMMENT '订单编号',
  `sku_id` bigint(20) DEFAULT NULL COMMENT 'sku_id',
  `sku_name` varchar(200) DEFAULT NULL COMMENT 'sku 名称(冗余)',
  `img_url` varchar(200) DEFAULT NULL COMMENT '图片名称(冗余)',
  `order_price` decimal(10,2) DEFAULT NULL COMMENT '购买价格(下单时 sku 价格)',
  `sku_num` varchar(200) DEFAULT NULL COMMENT '购买个数',
  `create_time` datetime DEFAULT NULL COMMENT '创立工夫',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='订单详情表';

3. 商品表(sku_info)

CREATE TABLE `sku_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'skuid(itemID)',
  `spu_id` bigint(20) DEFAULT NULL COMMENT 'spuid',
  `price` decimal(10,0) DEFAULT NULL COMMENT '价格',
  `sku_name` varchar(200) DEFAULT NULL COMMENT 'sku 名称',
  `sku_desc` varchar(2000) DEFAULT NULL COMMENT '商品规格形容',
  `weight` decimal(10,2) DEFAULT NULL COMMENT '分量',
  `tm_id` bigint(20) DEFAULT NULL COMMENT '品牌(冗余)',
  `category3_id` bigint(20) DEFAULT NULL COMMENT '三级分类 id(冗余)',
  `sku_default_img` varchar(200) DEFAULT NULL COMMENT '默认显示图片(冗余)',
  `create_time` datetime DEFAULT NULL COMMENT '创立工夫',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='商品表';

4. 商品一级类目表(base_category1)

CREATE TABLE `base_category1` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(10) NOT NULL COMMENT '分类名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='一级分类表';

5. 商品二级类目表(base_category2)

CREATE TABLE `base_category2` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(200) NOT NULL COMMENT '二级分类名称',
  `category1_id` bigint(20) DEFAULT NULL COMMENT '一级分类编号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='二级分类表';

6. 商品三级类目表(base_category3)

CREATE TABLE `base_category3` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(200) NOT NULL COMMENT '三级分类名称',
  `category2_id` bigint(20) DEFAULT NULL COMMENT '二级分类编号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='三级分类表';

7. 省份表(区域表(base_region)base_province)

CREATE TABLE `base_province` (`id` int(20) DEFAULT NULL COMMENT 'id',
  `name` varchar(20) DEFAULT NULL COMMENT '省名称',
  `region_id` int(20) DEFAULT NULL COMMENT '大区 id',
  `area_code` varchar(20) DEFAULT NULL COMMENT '行政区位码'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

8. 区域表(base_region)

CREATE TABLE `base_region` (`id` int(20) NOT NULL COMMENT '大区 id',
  `region_name` varchar(20) DEFAULT NULL COMMENT '大区名称',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4. 数据处理流程

1. ods 层数据同步

对于 ODS 层的数据同步这里就不具体开展。次要应用 canal 解析 MySQL 的 binlog 日志,而后将其写入到 Kafka 对应的 topic 中。因为篇幅限度,不会对具体的细节进行阐明。同步之后的后果如下图所示:

2. DIM 层数据筹备

本案例中将维表存储在了 MySQL 中,理论生产中会用 HBase 存储维表数据。咱们次要用到两张维表:区域维表和商品维表。处理过程如下:

  • 区域维表

首先将 mydw.base_provincemydw.base_region这个主题对应的数据抽取到 MySQL 中,次要应用 Flink SQL 的 Kafka 数据源对应的 canal-json 格局,留神:在执行装载之前,须要先在 MySQL 中创立对应的表,本文应用的 MySQL 数据库的名字为 dim,用于寄存维表数据。如下:

-- -------------------------
--   省份
--   kafka Source
-- ------------------------- 
DROP TABLE IF EXISTS `ods_base_province`;
CREATE TABLE `ods_base_province` (
  `id` INT,
  `name` STRING,
  `region_id` INT ,
  `area_code`STRING
) WITH(
'connector' = 'kafka',
 'topic' = 'mydw.base_province',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- -------------------------
--   省份
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `base_province`;
CREATE TABLE `base_province` (
    `id` INT,
    `name` STRING,
    `region_id` INT ,
    `area_code`STRING,
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'base_province', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--   省份
--   MySQL Sink Load Data
-- ------------------------- 
INSERT INTO base_province
SELECT *
FROM ods_base_province;
 
-- -------------------------
--   区域
--   kafka Source
-- ------------------------- 
DROP TABLE IF EXISTS `ods_base_region`;
CREATE TABLE `ods_base_region` (
  `id` INT,
  `region_name` STRING
) WITH(
'connector' = 'kafka',
 'topic' = 'mydw.base_region',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- -------------------------
--   区域
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `base_region`;
CREATE TABLE `base_region` (
    `id` INT,
    `region_name` STRING,
     PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'base_region', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--   区域
--   MySQL Sink Load Data
-- ------------------------- 
INSERT INTO base_region
SELECT *
FROM ods_base_region;

通过下面的步骤,将创立维表所须要的原始数据曾经存储到了 MySQL 中,接下来就须要在 MySQL 中创立维表,咱们应用下面的两张表,创立一张视图:dim_province作为维表:

-- ---------------------------------
-- DIM 层, 区域维表,
-- 在 MySQL 中创立视图
-- ---------------------------------
DROP VIEW IF EXISTS dim_province;
CREATE VIEW dim_province AS
SELECT
  bp.id AS province_id,
  bp.name AS province_name,
  br.id AS region_id,
  br.region_name AS region_name,
  bp.area_code AS area_code
FROM base_region br 
     JOIN base_province bp ON br.id= bp.region_id;

这样咱们所须要的维表:dim_province就创立好了,只须要在维表 join 时,应用 Flink SQL 创立 JDBC 的数据源,就能够应用该维表了。同理,咱们应用雷同的办法创立商品维表,具体如下:

-- -------------------------
--  一级类目表
--   kafka Source
-- ------------------------- 
DROP TABLE IF EXISTS `ods_base_category1`;
CREATE TABLE `ods_base_category1` (
  `id` BIGINT,
  `name` STRING
)WITH(
 'connector' = 'kafka',
 'topic' = 'mydw.base_category1',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ;
 
-- -------------------------
--  一级类目表
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `base_category1`;
CREATE TABLE `base_category1` (
    `id` BIGINT,
    `name` STRING,
     PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'base_category1', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--  一级类目表
--   MySQL Sink Load Data
-- ------------------------- 
 
INSERT INTO base_category1
SELECT *
FROM ods_base_category1;
 
-- -------------------------
--  二级类目表
--   kafka Source
-- ------------------------- 
DROP TABLE IF EXISTS `ods_base_category2`;
CREATE TABLE `ods_base_category2` (
  `id` BIGINT,
  `name` STRING,
  `category1_id` BIGINT
)WITH(
'connector' = 'kafka',
 'topic' = 'mydw.base_category2',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ;
 
-- -------------------------
--  二级类目表
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `base_category2`;
CREATE TABLE `base_category2` (
    `id` BIGINT,
    `name` STRING,
    `category1_id` BIGINT,
     PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'base_category2', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--  二级类目表
--   MySQL Sink Load Data
-- ------------------------- 
INSERT INTO base_category2
SELECT *
FROM ods_base_category2;
 
-- -------------------------
-- 三级类目表
--   kafka Source
-- ------------------------- 
DROP TABLE IF EXISTS `ods_base_category3`;
CREATE TABLE `ods_base_category3` (
  `id` BIGINT,
  `name` STRING,
  `category2_id` BIGINT
)WITH(
'connector' = 'kafka',
 'topic' = 'mydw.base_category3',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- -------------------------
--  三级类目表
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `base_category3`;
CREATE TABLE `base_category3` (
    `id` BIGINT,
    `name` STRING,
    `category2_id` BIGINT,
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'base_category3', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--  三级类目表
--   MySQL Sink Load Data
-- ------------------------- 
INSERT INTO base_category3
SELECT *
FROM ods_base_category3;
 
-- -------------------------
--   商品表
--   Kafka Source
-- ------------------------- 
 
DROP TABLE IF EXISTS `ods_sku_info`;
CREATE TABLE `ods_sku_info` (
  `id` BIGINT,
  `spu_id` BIGINT,
  `price` DECIMAL(10,0),
  `sku_name` STRING,
  `sku_desc` STRING,
  `weight` DECIMAL(10,2),
  `tm_id` BIGINT,
  `category3_id` BIGINT,
  `sku_default_img` STRING,
  `create_time` TIMESTAMP(0)
) WITH(
 'connector' = 'kafka',
 'topic' = 'mydw.sku_info',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- -------------------------
--   商品表
--   MySQL Sink
-- ------------------------- 
DROP TABLE IF EXISTS `sku_info`;
CREATE TABLE `sku_info` (
  `id` BIGINT,
  `spu_id` BIGINT,
  `price` DECIMAL(10,0),
  `sku_name` STRING,
  `sku_desc` STRING,
  `weight` DECIMAL(10,2),
  `tm_id` BIGINT,
  `category3_id` BIGINT,
  `sku_default_img` STRING,
  `create_time` TIMESTAMP(0),
   PRIMARY KEY (tm_id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'sku_info', -- MySQL 中的待插入数据的表
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'sink.buffer-flush.interval' = '1s'
);
 
-- -------------------------
--   商品
--   MySQL Sink Load Data
-- ------------------------- 
INSERT INTO sku_info
SELECT *
FROM ods_sku_info;

通过下面的步骤,咱们能够将创立商品维表的根底数据表同步到 MySQL 中,同样须要提前创立好对应的数据表。接下来咱们应用下面的根底表在 mySQL 的 dim 库中创立一张视图:dim_sku_info,用作后续应用的维表。

-- ---------------------------------
-- DIM 层, 商品维表,
-- 在 MySQL 中创立视图
-- ---------------------------------
CREATE VIEW dim_sku_info AS
SELECT
  si.id AS id,
  si.sku_name AS sku_name,
  si.category3_id AS c3_id,
  si.weight AS weight,
  si.tm_id AS tm_id,
  si.price AS price,
  si.spu_id AS spu_id,
  c3.name AS c3_name,
  c2.id AS c2_id,
  c2.name AS c2_name,
  c3.id AS c1_id,
  c3.name AS c1_name
FROM
(
  sku_info si 
  JOIN base_category3 c3 ON si.category3_id = c3.id
  JOIN base_category2 c2 ON c3.category2_id =c2.id
  JOIN base_category1 c1 ON c2.category1_id = c1.id
);

至此,咱们所须要的维表数据曾经筹备好了,接下来开始解决 DWD 层的数据。

3. DWD 层数据处理

通过下面的步骤,咱们曾经将所用的维表曾经筹备好了。接下来咱们将对 ODS 的原始数据进行解决,加工成 DWD 层的明细宽表。具体过程如下:

-- -------------------------
--   订单详情
--   Kafka Source
-- ------------------------- 
 
DROP TABLE IF EXISTS `ods_order_detail`;
CREATE TABLE `ods_order_detail`(
  `id` BIGINT,
  `order_id` BIGINT,
  `sku_id` BIGINT,
  `sku_name` STRING,
  `img_url` STRING,
  `order_price` DECIMAL(10,2),
  `sku_num` INT,
  `create_time` TIMESTAMP(0)
) WITH(
 'connector' = 'kafka',
 'topic' = 'mydw.order_detail',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- -------------------------
--   订单信息
--   Kafka Source
-- -------------------------
DROP TABLE IF EXISTS `ods_order_info`;
CREATE TABLE `ods_order_info` (
  `id` BIGINT,
  `consignee` STRING,
  `consignee_tel` STRING,
  `total_amount` DECIMAL(10,2),
  `order_status` STRING,
  `user_id` BIGINT,
  `payment_way` STRING,
  `delivery_address` STRING,
  `order_comment` STRING,
  `out_trade_no` STRING,
  `trade_body` STRING,
  `create_time` TIMESTAMP(0) ,
  `operate_time` TIMESTAMP(0) ,
  `expire_time` TIMESTAMP(0) ,
  `tracking_no` STRING,
  `parent_order_id` BIGINT,
  `img_url` STRING,
  `province_id` INT
) WITH(
'connector' = 'kafka',
 'topic' = 'mydw.order_info',
 'properties.bootstrap.servers' = 'kms-3:9092',
 'properties.group.id' = 'testGroup',
 'format' = 'canal-json' ,
 'scan.startup.mode' = 'earliest-offset' 
) ; 
 
-- ---------------------------------
-- DWD 层, 领取订单明细表 dwd_paid_order_detail
-- ---------------------------------
DROP TABLE IF EXISTS dwd_paid_order_detail;
CREATE TABLE dwd_paid_order_detail
(
  detail_id BIGINT,
  order_id BIGINT,
  user_id BIGINT,
  province_id INT,
  sku_id BIGINT,
  sku_name STRING,
  sku_num INT,
  order_price DECIMAL(10,0),
  create_time STRING,
  pay_time STRING
 ) WITH (
    'connector' = 'kafka',
    'topic' = 'dwd_paid_order_detail',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
-- ---------------------------------
-- DWD 层, 已领取订单明细表
-- 向 dwd_paid_order_detail 装载数据
-- ---------------------------------
INSERT INTO dwd_paid_order_detail
SELECT
  od.id,
  oi.id order_id,
  oi.user_id,
  oi.province_id,
  od.sku_id,
  od.sku_name,
  od.sku_num,
  od.order_price,
  oi.create_time,
  oi.operate_time
FROM
    (
    SELECT * 
    FROM ods_order_info
    WHERE order_status = '2' -- 已领取
    ) oi JOIN
    (
    SELECT *
    FROM ods_order_detail
    ) od 
    ON oi.id = od.order_id;

4. ADS 层数据

通过下面的步骤,咱们创立了一张 dwd_paid_order_detail 明细宽表,并将该表存储在了 Kafka 中。接下来咱们将应用这张明细宽表与维表进行 JOIN,失去咱们 ADS 应用层数据。

  • ads_province_index

首先在 MySQL 中创立对应的 ADS 指标表:ads_province_index

CREATE TABLE ads.ads_province_index(province_id INT(10),
  area_code VARCHAR(100),
  province_name VARCHAR(100),
  region_id INT(10),
  region_name VARCHAR(100),
  order_amount DECIMAL(10,2),
  order_count BIGINT(10),
  dt VARCHAR(100),
  PRIMARY KEY (province_id, dt) 
) ;

向 MySQL 的 ADS 层指标装载数据:

-- Flink SQL Cli 操作
-- ---------------------------------
-- 应用 DDL 创立 MySQL 中的 ADS 层表
-- 指标:1. 每天每个省份的订单数
--      2. 每天每个省份的订单金额
-- ---------------------------------
CREATE TABLE ads_province_index(
  province_id INT,
  area_code STRING,
  province_name STRING,
  region_id INT,
  region_name STRING,
  order_amount DECIMAL(10,2),
  order_count BIGINT,
  dt STRING,
  PRIMARY KEY (province_id, dt) NOT ENFORCED  
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/ads',
    'table-name' = 'ads_province_index', 
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe'
);
-- ---------------------------------
-- dwd_paid_order_detail 已领取订单明细宽表
-- ---------------------------------
CREATE TABLE dwd_paid_order_detail
(
  detail_id BIGINT,
  order_id BIGINT,
  user_id BIGINT,
  province_id INT,
  sku_id BIGINT,
  sku_name STRING,
  sku_num INT,
  order_price DECIMAL(10,2),
  create_time STRING,
  pay_time STRING
 ) WITH (
    'connector' = 'kafka',
    'topic' = 'dwd_paid_order_detail',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
 
-- ---------------------------------
-- tmp_province_index
-- 订单汇总长期表
-- ---------------------------------
CREATE TABLE tmp_province_index(
    province_id INT,
    order_count BIGINT,-- 订单数
    order_amount DECIMAL(10,2), -- 订单金额
    pay_date DATE
)WITH (
    'connector' = 'kafka',
    'topic' = 'tmp_province_index',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
-- ---------------------------------
-- tmp_province_index
-- 订单汇总长期表数据装载
-- ---------------------------------
INSERT INTO tmp_province_index
SELECT
      province_id,
      count(distinct order_id) order_count,-- 订单数
      sum(order_price * sku_num) order_amount, -- 订单金额
      TO_DATE(pay_time,'yyyy-MM-dd') pay_date
FROM dwd_paid_order_detail
GROUP BY province_id,TO_DATE(pay_time,'yyyy-MM-dd')
;
-- ---------------------------------
-- tmp_province_index_source
-- 应用该长期汇总表,作为数据源
-- ---------------------------------
CREATE TABLE tmp_province_index_source(
    province_id INT,
    order_count BIGINT,-- 订单数
    order_amount DECIMAL(10,2), -- 订单金额
    pay_date DATE,
    proctime as PROCTIME()   -- 通过计算列产生一个解决工夫列) WITH (
    'connector' = 'kafka',
    'topic' = 'tmp_province_index',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
 
-- ---------------------------------
-- DIM 层, 区域维表,
-- 创立区域维表数据源
-- ---------------------------------
DROP TABLE IF EXISTS `dim_province`;
CREATE TABLE dim_province (
  province_id INT,
  province_name STRING,
  area_code STRING,
  region_id INT,
  region_name STRING ,
  PRIMARY KEY (province_id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'dim_province', 
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'scan.fetch-size' = '100'
);
 
-- ---------------------------------
-- 向 ads_province_index 装载数据
-- 维表 JOIN
-- ---------------------------------
 
INSERT INTO ads_province_index
SELECT
  pc.province_id,
  dp.area_code,
  dp.province_name,
  dp.region_id,
  dp.region_name,
  pc.order_amount,
  pc.order_count,
  cast(pc.pay_date as VARCHAR)
FROM
tmp_province_index_source pc
  JOIN dim_province FOR SYSTEM_TIME AS OF pc.proctime as dp 
  ON dp.province_id = pc.province_id;

当提交工作之后:察看 Flink WEB UI

查看 ADS 层的 ads_province_index 表数据:

  • ads_sku_index

首先在 MySQL 中创立对应的 ADS 指标表:ads_sku_index

CREATE TABLE ads_sku_index
(sku_id BIGINT(10),
  sku_name VARCHAR(100),
  weight DOUBLE,
  tm_id BIGINT(10),
  price DOUBLE,
  spu_id BIGINT(10),
  c3_id BIGINT(10),
  c3_name VARCHAR(100) ,
  c2_id BIGINT(10),
  c2_name VARCHAR(100),
  c1_id BIGINT(10),
  c1_name VARCHAR(100),
  order_amount DOUBLE,
  order_count BIGINT(10),
  sku_count BIGINT(10),
  dt varchar(100),
  PRIMARY KEY (sku_id,dt)
);

向 MySQL 的 ADS 层指标装载数据:

-- ---------------------------------
-- 应用 DDL 创立 MySQL 中的 ADS 层表
-- 指标:1. 每天每个商品对应的订单个数
--      2. 每天每个商品对应的订单金额
--      3. 每天每个商品对应的数量
-- ---------------------------------
CREATE TABLE ads_sku_index
(
  sku_id BIGINT,
  sku_name VARCHAR,
  weight DOUBLE,
  tm_id BIGINT,
  price DOUBLE,
  spu_id BIGINT,
  c3_id BIGINT,
  c3_name VARCHAR ,
  c2_id BIGINT,
  c2_name VARCHAR,
  c1_id BIGINT,
  c1_name VARCHAR,
  order_amount DOUBLE,
  order_count BIGINT,
  sku_count BIGINT,
  dt varchar,
  PRIMARY KEY (sku_id,dt) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/ads',
    'table-name' = 'ads_sku_index', 
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe'
);
 
-- ---------------------------------
-- dwd_paid_order_detail 已领取订单明细宽表
-- ---------------------------------
CREATE TABLE dwd_paid_order_detail
(
  detail_id BIGINT,
  order_id BIGINT,
  user_id BIGINT,
  province_id INT,
  sku_id BIGINT,
  sku_name STRING,
  sku_num INT,
  order_price DECIMAL(10,2),
  create_time STRING,
  pay_time STRING
 ) WITH (
    'connector' = 'kafka',
    'topic' = 'dwd_paid_order_detail',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
 
-- ---------------------------------
-- tmp_sku_index
-- 商品指标统计
-- ---------------------------------
CREATE TABLE tmp_sku_index(
    sku_id BIGINT,
    order_count BIGINT,-- 订单数
    order_amount DECIMAL(10,2), -- 订单金额
 order_sku_num BIGINT,
    pay_date DATE
)WITH (
    'connector' = 'kafka',
    'topic' = 'tmp_sku_index',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
-- ---------------------------------
-- tmp_sku_index
-- 数据装载
-- ---------------------------------
INSERT INTO tmp_sku_index
SELECT
      sku_id,
      count(distinct order_id) order_count,-- 订单数
      sum(order_price * sku_num) order_amount, -- 订单金额
   sum(sku_num) order_sku_num,
      TO_DATE(pay_time,'yyyy-MM-dd') pay_date
FROM dwd_paid_order_detail
GROUP BY sku_id,TO_DATE(pay_time,'yyyy-MM-dd')
;
 
-- ---------------------------------
-- tmp_sku_index_source
-- 应用该长期汇总表,作为数据源
-- ---------------------------------
CREATE TABLE tmp_sku_index_source(
    sku_id BIGINT,
    order_count BIGINT,-- 订单数
    order_amount DECIMAL(10,2), -- 订单金额
    order_sku_num BIGINT,
    pay_date DATE,
    proctime as PROCTIME()   -- 通过计算列产生一个解决工夫列) WITH (
    'connector' = 'kafka',
    'topic' = 'tmp_sku_index',
    'scan.startup.mode' = 'earliest-offset',
    'properties.bootstrap.servers' = 'kms-3:9092',
    'format' = 'changelog-json'
);
-- ---------------------------------
-- DIM 层, 商品维表,
-- 创立商品维表数据源
-- ---------------------------------
DROP TABLE IF EXISTS `dim_sku_info`;
CREATE TABLE dim_sku_info (
  id BIGINT,
  sku_name STRING,
  c3_id BIGINT,
  weight DECIMAL(10,2),
  tm_id BIGINT,
  price DECIMAL(10,2),
  spu_id BIGINT,
  c3_name STRING,
  c2_id BIGINT,
  c2_name STRING,
  c1_id BIGINT,
  c1_name STRING,
  PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://kms-1:3306/dim',
    'table-name' = 'dim_sku_info', 
    'driver' = 'com.mysql.jdbc.Driver',
    'username' = 'root',
    'password' = '123qwe',
    'scan.fetch-size' = '100'
);
-- ---------------------------------
-- 向 ads_sku_index 装载数据
-- 维表 JOIN
-- ---------------------------------
INSERT INTO ads_sku_index
SELECT
  sku_id ,
  sku_name ,
  weight ,
  tm_id ,
  price ,
  spu_id ,
  c3_id ,
  c3_name,
  c2_id ,
  c2_name ,
  c1_id ,
  c1_name ,
  sc.order_amount,
  sc.order_count ,
  sc.order_sku_num ,
  cast(sc.pay_date as VARCHAR)
FROM
tmp_sku_index_source sc 
  JOIN dim_sku_info FOR SYSTEM_TIME AS OF sc.proctime as ds
  ON ds.id = sc.sku_id;

当提交工作之后:察看 Flink WEB UI

查看 ADS 层的 ads_sku_index 表数据

5. FineBI 展现

七、数据治理

数仓建设真正的难点不在于数仓设计,而在于后续业务倒退起来,业务线变的宏大之后的数据治理,包含资产治理、数据品质监控、数据指标体系的建设等。

其实数据治理的范畴很⼴,蕴含数据本⾝的治理、数据安全、数据品质、数据老本等。在 DAMA 数据管理常识体系指南 中,数据治理位于数据管理“车轮图”的正地方,是数据架构、数据建模、数据存储、数据安全、数据品质、元数据管理、主数据管理等 10 大数据管理畛域的总纲,为各项数据管理流动提供总体领导策略。

1. 数据治理之道是什么

1. 数据治理须要体系建设

为施展数据价值须要满足三个因素:正当的平台架构、欠缺的治理服务、体系化的经营伎俩

依据企业的规模、所属行业、数据量等状况抉择适合的平台架构;治理服务须要贯通数据全生命周期,保证数据在采集、加工、共享、存储、利用整个过程中的完整性、准确性、一致性和实效性;经营伎俩则该当包含标准的优化、组织的优化、平台的优化以及流程的优化等等方面。

2. 数据治理须要夯实根底

数据治理须要循序渐进,但在建设初期至多须要关注三个方面:数据标准、数据品质、数据安全。规范化的模型治理是保障数据能够被治理的前提条件,高质量的数据是数据可用的前提条件,数据的平安管控是数据能够共享替换的前提条件。

3. 数据治理须要 IT 赋能

数据治理不是一堆标准文档的堆砌,而是须要将治理过程中所产生的的标准、流程、规范落地到 IT 平台上,在数据生产过程中通过“以终为始”前向的形式进行数据治理,防止预先稽核带来各种被动和运维老本的减少。

4. 数据治理须要聚焦数据

数据治理的实质是治理数据,因而须要增强元数据管理和主数据管理,从源头治理数据,补齐数据的相干属性和信息,比方:元数据、品质、平安、业务逻辑、血统等,通过元数据驱动的形式治理数据生产、加工和应用。

5. 数据治理须要建管一体化

数据模型血统与任务调度的一致性是建管一体化的要害,有助于解决数据管理与数据生产口径不统一的问题,避免出现两张皮的低效管理模式。

2. 浅谈数据治理形式

如下面所说,数据治理的范畴十分广,其中最重要的是数据品质治理,而数据品质波及的范畴也很广,贯通数仓的整个生命周期,从 数据产生 -> 数据接入 -> 数据存储 -> 数据处理 -> 数据输入 -> 数据展现 ,每个阶段都须要品质治理,评估维度包含 完整性、规范性、一致性、准确性、唯一性、关联性 等。

在零碎建设的各个阶段都应该依据规范进行数据品质检测和标准,及时进行治理,防止预先的荡涤工作。

品质检测可参考以下维度:

维度 衡量标准
完整性 业务指定必须的数据是否缺失,不容许为空字符或者空值等。例如,数据源是否残缺、维度取值是否残缺、数据取值是否残缺等
时效性 当须要应用时,数据是否反映以后事实。即数据必须及时,可能满足系统对数据工夫的要求。例如解决(获取、整顿、荡涤、加载等)的及时性
唯一性 在指定的数据集中数据值是否惟一
参照完整性 数据项是否在父表中有定义
依赖一致性 数据项取值是否满足与其余数据项之间的依赖关系
正确性 数据内容和定义是否统一
精确性 数据精度是否达到业务规定要求的位数
技术有效性 数据项是否按已定义的格局规范组织
业务有效性 数据项是否合乎已定义的
可信度 依据客户考察或客户被动提供取得
可用性 数据可用的工夫和数据须要被拜访工夫的比例
可拜访性 数据是否便于自动化读取

上面是依据美团的技术文章总结的几点具体治理形式:

1. 标准治理

标准是数仓建设的保障。为了避免出现指标反复建设和数据品质差的状况,对立依照最具体、可落地的办法进行标准建设。

(1) 词根

词根是维度和指标治理的根底,划分为一般词根与专有词根,进步词根的易用性和关联性。

  • 一般词根:形容事物的最小单元体,如:交易 -trade。
  • 专有词根:具备约定成俗或行业专属的形容体,如:美元 -USD。

(2) 表命名标准

通用标准

  • 表名、字段名采纳一个下划线分隔词根(示例:clienttype->client_type)。
  • 每局部应用小写英文单词,属于通用字段的必须满足通用字段信息的定义。
  • 表名、字段名需以字母为结尾。
  • 表名、字段名最长不超过 64 个英文字符。
  • 优先应用词根中已有关键字(数仓标准配置中的词根治理),定期 Review 新增命名的不合理性。
  • 在表名自定义局部禁止采纳非标准的缩写。

表命名规定

  • 表名称 = 类型 + 业务主题 + 子主题 + 表含意 + 存储格局 + 更新频率 + 结尾,如下图所示:

(3) 指标命名标准

联合指标的个性以及词根治理标准,将指标进行结构化解决。

  1. 根底指标词根,即所有指标必须蕴含以下根底词根:

  1. 业务修饰词,用于形容业务场景的词汇,例如 trade- 交易。

3. 日期修饰词,用于润饰业务产生的工夫区间。

4. 聚合修饰词,对后果进行汇集操作。

5. 根底指标,繁多的业务修饰词 + 根底指标词根构建根底指标,例如:交易金额 -trade_amt。

6. 派生指标,多修饰词 + 根底指标词根构建派生指标。派生指标继承根底指标的个性,例如:装置门店数量 -install_poi_cnt。

7. 一般指标命名标准,与字段命名标准统一,由词汇转换即能够。

2. 架构治理

(1) 数据分层

优良牢靠的数仓体系,往往须要清晰的数据分层构造,即要保证数据层的稳固又要屏蔽对上游的影响,并且要防止链路过长,个别的分层架构如下:

(2) 数据流向

稳固业务依照规范的数据流向进行开发,即 ODS–>DWD–>DWA–>APP。非稳固业务或探索性需要,能够遵循 ODS->DWD->APP 或者 ODS->DWD->DWT->APP 两个模型数据流。在保障了数据链路的合理性之后,又在此基础上确认了模型分层援用准则:

  • 失常流向:ODS>DWD->DWT->DWA->APP,当呈现 ODS >DWD->DWA->APP 这种关系时,阐明主题域未笼罩全。应将 DWD 数据落到 DWT 中,对于应用频度非常低的表容许 DWD->DWA。
  • 尽量避免呈现 DWA 宽表中应用 DWD 又应用(该 DWD 所归属主题域)DWT 的表。
  • 同一主题域内对于 DWT 生成 DWT 的表,原则上要尽量避免,否则会影响 ETL 的效率。
  • DWT、DWA 和 APP 中禁止间接应用 ODS 的表,ODS 的表只能被 DWD 援用。
  • 禁止呈现反向依赖,例如 DWT 的表依赖 DWA 的表。
3. 元数据治理

元数据可分为技术元数据和业务元数据:

技术元数据 为开发和治理数据仓库的 IT 人员应用,它形容了与数据仓库开发、治理和保护相干的数据,包含数据源信息、数据转换形容、数据仓库模型、数据荡涤与更新规定、数据映射和拜访权限等。

常见的技术元数据有:

  • 存储元数据:如表、字段、分区等信息。
  • 运行元数据:如大数据平台上所有作业运行等信息:相似于 Hive Job 日志,包含作业类型、实例名称、输入输出、SQL、运行参数、执行工夫,执行引擎等。
  • 数据开发平台中数据同步、计算工作、任务调度等信息:包含数据同步的输入输出表和字段,以及同步工作自身的节点信息:计算工作次要有输入输出、工作自身的节点信息 任务调度次要有工作的依赖类型、依赖关系等,以及不同类型调度工作的运行日志等。
  • 数据品质和运维相干元数据:如工作监控、运维报警、数据品质、故障等信息,包含工作监控运行日志、告警配置及运行日志、故障信息等。

业务元数据 为管理层和业务剖析人员服务,从业务角度形容数据,包含商务术语、数据仓库中有什么数据、数据的地位和数据的可用性等,帮忙业务人员更好地了解数据仓库中哪些数据是可用的以及如何应用。

  • 常见的业务元数据有维度及属性(包含维度编码,字段类型,创建人,创立工夫,状态等)、业务过程、指标(蕴含指标名称, 指标编码,业务口径,指标类型,责任人,创立工夫,状态,sql 等),安全等级,计算逻辑等的规范化定义,用于更好地治理和应用数据。数据利用元数据,如数据报表、数据产品等的配置和运行元数据。

元数据不仅定义了数据仓库中数据的模式、起源、抽取和转换规则等,而且是整个数据仓库零碎运行的根底,元数据把数据仓库零碎中各个涣散的组件分割起来,组成了一个有机的整体

元数据治理次要解决三个问题

  1. 通过建设相应的组织、流程和工具,推动业务规范的落地施行,实现指标的标准定义,打消指标认知的歧义;
  2. 基于业务现状和将来的演进形式,对业务模型进行形象,制订清晰的主题、业务过程和剖析方向,构建齐备的技术元数据,对物理模型进行精确欠缺的形容,并买通技术元数据与业务元数据的关系,对物理模型进行齐备的刻画;
  3. 通过元数据建设,为应用数据提效,解决“找数、了解数、评估”难题以及“取数、数据可视化”等难题。
4. 平安治理

围绕数据安全规范,首先要有数据的分级、分类规范,确保数据在上线前有着精确的密级。第二,针对数据应用方,要有明确的角色受权规范,通过分级分类和角色受权,来保障重要数据拿不走。第三,针对敏感数据,要有隐衷治理规范,保障敏感数据的平安存储,即便未受权用户绕过权限治理拿到敏感数据,也要确保其看不懂。第四,通过制订审计规范,为后续的审计提供审计根据,确保数据走不脱。

5. 数据生命周期治理

任何事物都具备肯定的生命周期,数据也不例外。从数据的产生、加工、应用乃至沦亡都应该有一个迷信的治理方法,将极少或者不再应用的数据从零碎中剥离进去,并通过核实的存储设备进行保留,不仅可能进步零碎的运行效率,更好的服务客户,还能大幅度缩小因为数据长期保留带来的贮存老本。数据生命周期个别蕴含在线阶段、归档阶段(有时还会进一步划分为在线归档阶段和离线归档阶段)、销毁阶段三大阶段,治理内容包含建设正当的数据类别,针对不同类别的数据制订各个阶段的保留工夫、存储介质、清理规定和形式、注意事项等。

从上图数据生命周期中各参数间的关系中咱们能够理解到,数据生命周期治理能够使得高价值数据的查问效率大幅晋升,而且高价格的存储介质的洽购量也能够缩小很多;然而随着数据的应用水平的降落,数据被逐步归档,查问工夫也缓缓的变长;最初随着数据的应用频率和价值根本没有了之后,就能够逐步销毁了。


猜你喜爱:

  1. 美团数据平台及数仓建设实际,超十万字总结
  2. 上百本优质大数据书籍,附必读清单(大数据宝藏)
  3. 五万字 | 耗时一个月整顿出这份 Hadoop 吐血宝典

八、数据品质建设

数据治理的范畴十分广,蕴含数据本⾝的治理、数据安全、数据品质、数据老本等。在这么多治理内容中,大家想下最重要的治理是什么?当然是 数据品质治理,因为数据品质是数据分析论断有效性和准确性的根底,也是这所有的前提。所以如何保障数据品质,确保数据可用性是数据仓库建设中不容忽视的环节。

数据品质波及的范畴也很广,贯通数仓的整个生命周期,从 数据产生 -> 数据接入 -> 数据存储 -> 数据处理 -> 数据输入 -> 数据展现,每个阶段都须要品质治理。

在零碎建设的各个阶段都应该依据规范进行数据品质检测和标准,及时进行治理,防止预先的荡涤工作。

本文档首发于公众号【五分钟学大数据】,残缺的数据治理及数仓建设文章公众号上都有!

1. 为什么要进行数据品质评估

很多刚入门的数据人,拿到数据后会立即开始对数据进行各种探查、统计分析等,希图能立刻发现数据背地暗藏的信息和常识。然而忙活了一阵才颓然发现,并不能提炼出太多有价值的信息,白白浪费了大量的工夫和精力。比方和数据打交道的过程中,可能会呈现以下的场景:

场景一:作为数据分析人员,要统计一下近 7 天用户的购买状况,后果从数仓中统计完发现,很多数据产生了重复记录,甚至有些数据统计单位不对立。

场景二:业务看报表,发现某一天的成交 gmv 暴涨,通过排查发现,是当天的数据缺失。

造成这一状况的一个重要因素就是漠视了对数据品质的主观评估,没有制订正当的衡量标准,导致没有发现数据已呈现问题。所以,进行迷信、主观的数据品质衡量标准是十分必要且非常重要的。

2. 数据品质衡量标准

如何评估数据品质的好坏,业界有不同的规范,我总结了以下六个维度进行评估,包含 完整性、规范性、一致性、准确性、唯一性、及时性

  1. 数据完整性

完整性指的是数据信息是否存在缺失的情况,数据缺失的状况可能是整个数据记录缺失,也可能是数据中某个字段信息的记录缺失。

  1. 数据规范性

规范性指的是形容数据遵循预约的语法规定的水平,是否合乎其定义,比方数据的类型、格局、取值范畴等。

  1. 数据一致性

一致性是指数据是否遵循了对立的标准,数据汇合是否放弃了对立的格局。数据品质的一致性次要体现在数据记录的标准和数据是否合乎逻辑,一致性并不意味着数值上的相对雷同,而是数据收集、解决的办法和规范的统一。常见的一致性指标有:ID 重合度、属性统一、取值统一、采集办法统一、转化步骤统一。

  1. 数据准确性

准确性是指数据记录的信息是否存在异样或谬误。和一致性不一样,存在准确性问题的数据不仅仅只是规定上的不统一,更为常见的数据准确性谬误就如乱码,其次异样的大或者小的数据也是不符合条件的数据。常见的准确性指标有:缺失值占比、谬误值占比、异样值占比、抽样偏差、数据噪声。

  1. 数据唯一性

唯一性指的是数据库的数据不存在反复的情景。比方实在成交 1 万条,但数据表有 3000 条反复了,成了 1.3 万条成交记录,这种数据不合乎数据唯一性。

  1. 数据及时性

及时性是指数据从产生到能够查看的工夫距离,也叫数据的延时时长。比方一份数据是统计离线今日的,后果都是第二天甚至第三天能力统计完,这种数据不合乎数据及时性。

_还有一些其余的衡量标准,在此简略列出_:

维度 衡量标准
参照完整性 数据项是否在父表中有定义
依赖一致性 数据项取值是否满足与其余数据项之间的依赖关系
正确性 数据内容和定义是否统一
精确性 数据精度是否达到业务规定要求的位数
技术有效性 数据项是否按已定义的格局规范组织
业务有效性 数据项是否合乎已定义的
可信度 依据客户考察或客户被动提供取得
可用性 数据可用的工夫和数据须要被拜访工夫的比例
可拜访性 数据是否便于自动化读取

3. 数据品质治理流程

本节流程如下图所示:

1. 数据资产等级

1) 等级定义

依据 当数据品质不满足完整性、规范性、一致性、准确性、唯一性、及时性时,对业务的影响水平大小 来划分数据的资产等级。

  1. 毁灭性:数据一旦出错,会引起微小的资产损失,面临重大收益受损等。标记为 L1
  2. 全局性:数据用于团体业务、企业级成果评估和重要决策工作等。标记为 L2
  3. 局部性:数据用于某个业务线的日常经营、剖析报告等,如果呈现问题会给该业务线造成肯定的影响或影响其工作效率。标记为 L3
  4. 一般性:数据用于日常数据分析,呈现问题的带来的影响很小。标记为 L4
  5. 未知性质:无奈追溯数据的利用场景。标记为 Lx

重要水平:L1>L2>L3>L4>Lx。如果一份数据呈现在多个利用场景中,则依据其最重要水平进行标记。

2) 等级划分

定义数据资产等级后,咱们能够从数据流程链路开始进行数据资产等级标记,实现数据资产等级确认,给不同的数据定义不同的重要水平。

1. 剖析数据链路

数据是从业务零碎中产生的,通过同步工具进入数据仓库零碎中,在数据仓库中进行个别意义上的荡涤、加工、整合、算法、模型等一系列运算后,再通过同步工具输入到数据产品中进行生产。而从业务零碎到数据仓库再到数据产品都是以表的模式体现的,其流转过程如下图所示:

2. 标记数据资产等级

在所有数据链路上,整顿出生产各个表的利用业务。通过给这些利用业务划分数据资产等级,联合数据的上下游依赖关系,将整个链路打上某一类资产等级标签。

举例

假如公司有对立的订单服务中心。应用层的利用业务是依照业务线,商品类型和地区统计公司的订单数量和订单金额,命名为order_num_amount

假如该利用会影响到整个企业的重要业务决策,咱们能够把利用定级为 L2,从而 整个数据链路上的表的数据等级,都能够标记为L2-order_num_amount,始终标记到源数据业务零碎,如下图所示:

2. 数据加工过程卡点校验

1) 在线零碎数据校验

在线业务复杂多变,总是在一直地变更,每一次变更都会带来数据的变动,数据仓库须要适应这多变的业务倒退,及时做到数据的准确性。

基于此,在线业务的变更如何高效地告诉到离线数据仓库,同样也是须要思考的问题。为了保障在线数据和离线数据的一致性,咱们能够通过 工具 + 人员治理并行的形式 来尽可能的解决以上问题:既要在工具上主动捕获每一次业务的变动,同时也要求开发人员在意识上主动进行业务变更告诉。

1. 业务上线公布平台

监控业务上线公布平台上的重大业务变更,通过订阅这个公布过程,及时将变更内容告诉到数据部门。

因为业务零碎复杂多变,若日常公布变更频繁,那么每次都告诉数据部门,会造成不必要的资源节约。这时,咱们能够应用 之前曾经实现标记的数据资产等级标签,针对波及高等级数据利用的数据资产,整顿出哪些类型的业务变更会影响数据的加工或者影响数据统计口径的调整,则这些状况都必须及时告诉到数据部门。

如果公司没有本人的业务公布平台,那么就须要与业务部门约定好,_针对高等级的数据资产的业务变更,须要以邮件或者其余书面的阐明及时反馈到数据部门_。

2. 操作人员治理

工具只是辅助监管的一种伎俩,而应用工具的人员才是外围。数据资产等级的上下游买通过程须要告诉给在线业务零碎开发人员,使其晓得哪些是重要的外围数据资产,哪些临时还只是作为外部剖析数据应用,进步在线开发人员的数据风险意识。

能够通过培训的形式,_把数据品质治理的诉求,数据品质治理的整个数据加工过程,以及数据产品的利用形式及利用场景告知在线开发人员,使其理解数据的重要性、价值及危险_。确保在线开发人员在实现业务指标的同时,也要思考数据的指标,放弃业务端和数据段统一。

2) 离线零碎数据校验

数据从在线业务零碎到数据仓库再到数据产品的过程中,须要在数据仓库这一层实现数据的荡涤、加工。正是有了数据的加工,才有了数据仓库模型和数据仓库代码的建设。如何保障数据加过程中的品质,是离线数据仓库保障数据品质的一个重要环节。

在这些环节中,咱们能够采纳以下形式来保障数据品质:

  1. 代码提交核查

开发相干的规定引擎,辅助代码提交校验。规定分类大抵为:

  • _代码标准类规定_:如表命名标准、字段命名标准、生命周期设置、表正文等;
  • _代码品质类规定_:如分母为 0 揭示、NUll 值参加计算揭示等;
  • _代码性能类规定_:如大表揭示、反复计算监测、大小表 join 操作揭示等。
  1. 代码公布核查

增强测试环节,测试环境测试后再公布到生成环境,且生成环境测试通过后才算公布胜利。

  1. 工作变更或重跑数据

在进行数据更新操作前,须要告诉上游数据变更起因、变更逻辑、变更工夫等信息。上游没有异议后,再依照约定工夫执行变更公布操作。

3. 数据处理危险监控

危险点监控次要是针对数据在日常运行过程中容易呈现的危险进行监控并设置报警机制,次要包含 在线数据 离线数据 运行危险点监控。

1) 数据品质监控

在线业务零碎 的数据生产过程须要保证数据品质,次要依据业务规定对数据进行监控。

比方交易系统配置的一些监控规定,如订单拍下工夫、订单完结工夫、订单领取金额、订单状态流转等都配置了校验规定。订单拍下工夫必定不会大于当天工夫,也不会小于业务上线工夫,一旦出现异常的订单创立工夫,就会立即报警,同时报警给到多人。通过这种机制,能够及时发现并解决问题。

随着业务负责水平的晋升,会导致规定繁多、规定配置的运行老本增大,这时能够 依照咱们之前的数据资产等级有针对性的进行监控

离线数据 危险点监控次要包含对数据准确性和数据产出及时性的监控。对数据调度平台上所有数据处理调度进行监控。

咱们以阿里的 DataWorks 数据调度工具为例,DataWorks 是基于 MaxCompute 计算引擎的一站式开发工场,帮忙企业疾速实现数据集成、开发、治理、品质、平安等全套数据研发工作。

DataWorks 中的 DQC 通过配置数据品质校验规定,实现离线数据处理中的数据品质监控报警机制。

下图是 DQC 的工作流程图:

DQC 数据监控规定有强规定和弱规定:

  • 强规定:一旦触发报警就会阻断工作的执行(将工作置为失败状态,使上游工作不会被触发执行)。
  • 弱规定:只报警但不阻断工作的执行。

DQC 提供罕用的规定模板,包含 表行数较 N 天前稳定率、表空间大小较 N 天前稳定率、字段最大 / 最小 / 平均值相比 N 天前稳定率、字段空值 / 惟一个数 等。

DQC 查看其实也是运行 SQL 工作,只是这个工作是嵌套在主工作中的,一旦检查点太多天然就会影响整体的性能,因而还是 依赖数据产等级 来确定规定的配置状况。比方 L1、L2 类数据监控率要达到 90% 以上,规定类型须要三种及以上,而不重要的数据资产则不强制要求。

2) 数据及时性监控

在确保数据准确性的前提下,须要进一步让数据可能及时地提供服务,否则数据的价值将大幅度降低,甚至没有价值,所以 确保数据及时性也是保障数据品质重中之重的一环

  1. 工作优先级

对于 DataWorks 平台的调度工作,能够通过智能监控工具进行优先级设置。DataWorks 的调度是一个树形构造,当配置了叶子节点的优先级,这个优先级会传递到所有的上游节点,而叶子节点通常就是服务业务的生产节点。

因而,在优先级的设置上,要先确定业务的资产等级,等级越高的业务对应的生产节点优先级越高,优先调度并占用计算资源,确保高等级业务的准时产出。

总之,就是依照数据资产等级优先执行高等级数据资产的调度工作,优先保障高等级业务的数据需要。

  1. 工作报警

工作报警和优先级相似,通过 DataWorks 的智能监控工具进行配置,只须要配置叶子节点即可向上游传递报警配置。工作执行过程中,可能出错或提早,为了保障最重要数据(即资产等级高的数据)产出,须要立刻解决出错并染指解决提早。

  1. DataWorks 智能监控

DataWorks 进行离线任务调度时,提供智能监控工具,对调度工作进行监控告警。依据监控规定和工作运行状况,智能监控决策是否报警、何时报警、如何报警以及给谁报警。智能监控会主动抉择最正当的报警工夫、报警形式以及报警对象。

4. 最初

要想真正解决数据品质问题,就要 明确业务需要并从需要开始控制数据品质,并建设数据品质管理机制。从业务登程做问题定义,由工具主动、及时发现问题,明确问题责任人,通过邮件、短信等形式进行告诉,保障问题及时告诉到责任人。跟踪问题整改进度,保证数据品质问题全过程的治理。

九、数仓标准建设指南

1. 数仓公共开发标准

1. 档次调用标准

稳固业务 依照规范的数据流向进行开发,即 ODS –> DWD –> DWS –> APP。非稳固业务 或探索性需要,能够遵循 ODS -> DWD -> APP 或者 ODS -> DWD -> DWM ->APP 两个模型数据流。

在保障了数据链路的合理性之后,也必须保障模型分层援用准则:

  • 失常流向:ODS -> DWD -> DWM -> DWS -> APP,当呈现 ODS -> DWD -> DWS -> APP 这种关系时,阐明主题域未笼罩全。应将 DWD 数据落到 DWM 中,对于应用频度非常低的表容许 DWD -> DWS。
  • 尽量避免呈现 DWS 宽表中应用 DWD 又应用(该 DWD 所归属主题域)DWM 的表。
  • 同一主题域内对于 DWM 生成 DWM 的表,原则上要尽量避免,否则会影响 ETL 的效率。
  • DWM、DWS 和 APP 中禁止间接应用 ODS 的表,ODS 的表只能被 DWD 援用。
  • 禁止呈现反向依赖,例如 DWM 的表依赖 DWS 的表。

举例:

2. 数据类型标准

需对立规定不同的数据的数据类型,严格依照规定的数据类型执行:

  1. 金额 :double 或应用 decimal(11,2) 控制精度等, 明确单位是分还是元
  2. 字符串:string。
  3. id 类:bigint。
  4. 工夫:string。
  5. 状态:string

3. 数据冗余标准

宽表的冗余字段要确保:

  1. 冗余字段要应用高频,上游 3 个或以上应用
  2. 冗余字段引入 不应造成自身数据产生过多的延后
  3. 冗余字段 和已有字段的反复率不应过大,原则上不应超过 60%,如须要能够抉择 join 或原表拓展。

4. NULL 字段解决标准

  • 对于维度字段,需设置为 -1
  • 对于指标字段,需设置为 0

5. 指标口径标准

保障主题域内,指标口径统一,无歧义

通过数据分层,提供对立的数据进口,对立对外输入的数据口径,防止同一指标不同口径的状况产生。

1) 指标梳理

指标口径的不统一使得数据应用的老本极高,经常出现口径打架、重复核查数据的问题。在数据治理中,咱们将需要梳理到的所有指标进行进一步梳理,明确其口径,如果存在两个指标名称雷同,但口径不统一,先判断是否是进行合并,如须要同时存在,那么在命名上必须可能辨别开。

2) 指标治理

指标治理分为原子指标保护和派生指标保护。

原子指标:

  • 抉择原子指标的归属产线、业务板块、数据域、业务过程
  • 抉择原子指标的统计数据来源于该业务过程下的原始数据源
  • 录入原子指标的英文名称、中文名称、概述
  • 填写指标函数
  • 零碎依据指标函数主动生成原子指标的定义表达式
  • 零碎依据指标定义表达式以及数据源表生成原子指标 SQL

派生指标:

  • 在原子指标的根底之上抉择了一些维度或者润饰限定词。

6. 数据表解决标准

1) 增量表

新增数据,增量数据是上次导出之后的新数据。

  1. 记录每次减少的量,而不是总量;
  2. 增量表,只报变动量,无变动不必报;
  3. 每天一个分区。
2) 全量表

每天的所有的最新状态的数据。

  1. 全量表,有无变动,都要报;
  2. 每次上报的数据都是所有的数据(变动的 + 没有变动的);
  3. 只有一个分区。
3) 快照表

按日分区,记录截止数据日期的全量数据。

  1. 快照表,有无变动,都要报;
  2. 每次上报的数据都是所有的数据(变动的 + 没有变动的);
  3. 一天一个分区。
4) 拉链表

记录截止数据日期的全量数据。

  1. 记录一个事物从开始,始终到以后状态的所有变动的信息;
  2. 拉链表每次上报的都是历史记录的最终状态,是记录在以后时刻的历史总
    量;
  3. 以后记录存的是以后工夫之前的所有历史记录的最初变动量(总量);
  4. 只有一个分区。

7. 表的生命周期治理

这部分次要是要通过对历史数据的等级划分与对表类型的划分生成相应的生命周期治理矩阵。

1) 历史数据等级划分

次要将历史数据划分 P0、Pl、P2、P3 四个等级,其具体定义如下:

  • P0:十分重要的主题域数据和十分重要的利用数据,具备不可恢复性,如交易、日志、团体 KPI 数据、IPO 关联表。
  • Pl:重要的业务数据和重要的利用数据,具备不可恢复性,如重要的业务产品数据。
  • P2:重要的业务数据和重要的利用数据,具备可恢复性,如交易线 ETL 产生的两头过程数据。
  • P3:不重要的业务数据和不重要的利用数据,具备可恢复性,如某些 SNS 产品报表。
2) 表类型划分
  1. 事件型流水表(增量表)

事件型流水表(增量表)指数据无反复或者无主键数据,如日志。

  1. 事件型镜像表(增量表)

事件型镜像表(增量表)指业务过程性数据,有主键,然而对于同样主键的属性会产生迟缓变动,如交易、订单状态与工夫会依据业务产生变更。

  1. 维表

维表包含维度与维度属性数据,如用户表、商品表。

  1. Merge 全量表

Merge 全量表包含业务过程性数据或者维表数据。因为数据自身有新增的或者产生状态变更,对于同样主键的数据可能会保留多份,因而能够对这些数据依据主键进行 Merge 操作,主键对应的属性只会保留最新状态,历史状态保留在前一天分区 中。例如,用户表、交易表等都能够进行 Merge 操作。

  1. ETL 长期表

ETL 长期表是指 ETL 处理过程中产生的长期表数据,个别不倡议保留,最多 7 天。

  1. TT 长期数据

TT 拉取的数据和 DbSync 产生的长期数据最终会流转到 DS 层,ODS 层数据作为原始数据保留下来,从而使得 TT&DbSync 上游数据成为长期数据。这类数据不倡议保留很长时间,生命周期默认设置为 93 天,能够依据理论状况适当缩小保留天数。

7. 一般全量表

很多小业务数据或者产品数据,BI 个别是间接全量拉取,这种形式效率快,对存储压力也不是很大,而且表保留很长时间,能够依据历史数据等级确定保留策略。

通过上述历史数据等级划分与表类型划分,生成相应的生命周期治理矩阵,如下表所示:

2. 数仓各层开发标准

1. ODS 层设计规范

同步标准

  1. 一个零碎源表只容许同步一次;
  2. 全量初始化同步和增量同步解决逻辑要清晰;
  3. 以统计日期和工夫进行分区存储;
  4. 指标表字段在源表不存在时要主动填充解决。

表分类与生命周期

  1. ods 流水全量表
  • 不可再生的永恒保留;
  • 日志可按留存要求;
  • 按需设置保留非凡日期数据;
  • 按需设置保留非凡月份数据;
  1. ods 镜像型全量表
  • 举荐按天存储;
  • 对历史变动进行保留;
  • 最新数据存储在最大分区;
  • 历史数据按需保留;
  1. ods 增量数据
  • 举荐按天存储;
  • 有对应全量表的,倡议只保留 14 天数据;
  • 无对应全量表的,永恒保留;
  1. ods 的 etl 过程中的长期表
  • 举荐按需保留;
  • 最多保留 7 天;
  • 倡议用完即删,下次应用再生成;
  1. BDSync 非去重数据
  • 通过中间层保留,默认用完即删,不倡议保留。

数据品质

  1. 全量表必须配置唯一性字段标识;
  2. 对分区空数据进行监控;
  3. 对枚举类型字段,进行枚举值变动和散布监控;
  4. ods 表数据量级和记录数做环比监控;
  5. ods 全表都必须要有正文;

2. 公共维度层设计规范

1) 设计准则
  1. 一致性

共维度在不同的物理表中的字段名称、数据类型、数据内容必须保持一致(历史起因不统一,要做好版本控制)

  1. 维度的组合与拆分
  • 组合准则

将维度与关联性强的字段进行组合,一起查问,一起展现,两个维度必须具备人造的关系,如:商品的根本属性和所属品牌。

无相关性:如一些应用频率较小的杂项维度,能够构建一个汇合杂项维度的非凡属性。

行为维度:通过计算的度量,但上游当维度解决,例:点击量 0-1000,100-1000 等,能够做聚合分类。

  • 拆分与冗余

针对重要性,业务相关性、源、应用频率等可分为外围表、扩大表。

数据记录较大的维度,能够适当冗余一些子集。

2) 存储及生命周期治理

倡议按天分区。

  1. 3 个月内最大拜访跨度 <= 4 地利,倡议保留最近 7 天分区;
  2. 3 个月内最大拜访跨度 <=12 地利,倡议保留最近 15 天分区;
  3. 3 个月内最大拜访跨度 <=30 地利,倡议保留最近 33 天分区;
  4. 3 个月内最大拜访跨度 <=90 地利,倡议保留最近 120 天分区;
  5. 3 个月内最大拜访跨度 <=180 地利,倡议保留最近 240 天分区;
  6. 3 个月内最大拜访跨度 <=300 地利,倡议保留最近 400 天分区;

3. DWD 明细层设计规范

1) 存储及生命周期治理

倡议按天分区。

  1. 3 个月内最大拜访跨度 <= 4 地利,倡议保留最近 7 天分区;
  2. 3 个月内最大拜访跨度 <=12 地利,倡议保留最近 15 天分区;
  3. 3 个月内最大拜访跨度 <=30 地利,倡议保留最近 33 天分区;
  4. 3 个月内最大拜访跨度 <=90 地利,倡议保留最近 120 天分区;
  5. 3 个月内最大拜访跨度 <=180 地利,倡议保留最近 240 天分区;
  6. 3 个月内最大拜访跨度 <=300 地利,倡议保留最近 400 天分区;
2) 事务型事实表设计准则
  • 基于数据利用需要的剖析设计事务型事实表,联合上游较大的针对某个业务过程和剖析指标需要,可思考基于某个事件过程构建事务型实时表;
  • 个别选用事件的产生日期或工夫作为分区字段,便于扫描和裁剪;
  • 冗余子集准则,有利于升高后续 IO 开销;
  • 明细层事实表维度进化,缩小后续应用 join 老本。
3) 周期快照事实表
  • 周期快照事实表中的每行汇总了产生在某一规范周期,如某一天、某周、某月的多个度量事件。
  • 粒度是周期性的,不是个体的事务。
  • 通常蕴含许多事实,因为任何与事实表粒度统一的度量事件都是被容许的。
4) 累积快照事实表
  • 多个业务过程联结剖析而构建的事实表,如洽购单的流转环节。
  • 用于剖析事件工夫和工夫之间的距离周期。
  • 大量的且以后事务型不反对的,如敞开、发货等相干的统计。

4. DWS 公共汇总层设计规范

数据仓库的性能是数据仓库建设是否胜利的重要规范之一。汇集 次要是通过 汇总明细粒度数据 来取得改良查问性能的成果。通过拜访汇集数据,能够缩小数据库在响应查问时必须执行的工作量,可能疾速响应用户的查问,同时有利于缩小不同用拜访明细数据带来的后果不统一问题。

1) 汇集的根本准则
  • 一致性。汇集表必须提供与查问明细粒度数据统一的查问后果。
  • 防止繁多表设计。不要在同一个表中存储不同档次的汇集数据。
  • 汇集粒度可不同。汇集并不需要放弃与原始明细粒度数据一样的粒度,汇集只关怀所须要查问的维度。
2) 汇集的根本步骤

第一步:确定汇集维度

在原始明细模型中会存在多个形容事实的维度,如日期、商品类别、卖家等,这时候须要确定依据什么维度汇集,如果只关怀商品的交易额状况,那么就能够依据商品维度汇集数据。

第二步:确定一致性上钻

这时候要关怀是按月汇总还是按天汇总,是依照商品汇总还是依照类目汇总,如果依照类目汇总,还须要关怀是依照大类汇总还是小类汇总。当然,咱们要做的只是理解用户须要什么,而后依照他们想要的进行汇集。

第三步:确定汇集事实

在原始明细模型中可能会有多个事实的度量,比方在交易中有交易额、交易数量等,这时候要明确是依照交易额汇总还是依照成交数量汇总。

3) 公共汇总层设计准则

除了汇集根本的准则外,公共汇总层还必须遵循以下准则:

  • 数据专用性。汇总的汇集会有第三者应用吗?基于某个维度的汇集是不是常常用于数据分析中?如果答案是必定的,那么就有必要把明细数据通过汇总积淀到汇集表中。
  • 不跨数据域。数据域是在较高层次上对数据进行分类汇集的形象。如以业务
  • 辨别统计周期 。在表的命名上要能阐明数据的统计周期,如 _Id
    示意最近 1 天,_td 示意截至当天,_nd 示意最近 N 天。

3. 数仓命名标准

1. 词根设计规范

词根属于数仓建设中的标准,属于元数据管理的领域,当初把这个划到数据治理的一部分。残缺的数仓建设是蕴含数据治理的,只是当初谈到数仓偏差于数据建模,而谈到数据治理,更多的是对于数据标准、数据管理。

表命名,其实在很大水平上是对元数据形容的一种体现,表命名标准越欠缺,我 们能从表名获取到的信息就越多。比方:一部分业务是对于货架的,英文名是:rack,rack 就是一个词根,那咱们就在所有的表、字段等用到的中央都叫 rack,不要叫成 别的什么。这就是词根的作用,用来对立命名,表白同一个含意。

指标体系中有很多“率”的指标,都能够拆解成 XXX+ 率,率能够叫 rate,那我 们所有的指标都叫做 XXX+rate。

词根:能够用来对立表名、字段名、主题域名等等

举例:以流程图的形式来展现,更加直观和易懂,本图偏重 dwm 层表的命名 标准,其余命名是相似的情理:

第一个判断条件是该表的用处,是两头表、原始日志还是业务展现用的表 如果该表被判断为两头表,就会走入下一个判断条件:表是否有 group 操作 通过是否有 group 操作来判断该表该划分在 dwd 层还是 dwm 和 dws 层 如果不是 dwd 层,则须要判断该表是否是多个行为的汇总表(即宽表)最初再别离填上事业群、部门、业务线、自定义名称和更新频率等信息即可。

分层:表的应用范畴

事业群和部门:生产该表或者该数据的团队

业务线:表明该数据是哪个产品或者业务线相干

主题域:剖析问题的角度,对象实体

自定义:个别会尽可能多形容该表的信息,比方沉闷表、留存表等

更新周期:比如说天级还是月级更新

数仓表的命名标准如下

1. 数仓档次:

专用维度:dim

DM 层:dm

ODS 层:ods

DWD 层:dwd

DWS 层:dws

2. 周期 / 数据范畴:

日快照:d

增量:i

全量:f

周:w

拉链表:l

非分区全量表:a

2. 表命名标准

1) 惯例表

惯例表是咱们须要固化的表,是正式应用的表,是目前一段时间内须要去保护去 欠缺的表。

标准:分层前缀[dwd|dws|ads]_部门_业务域_主题域_XXX_更新周期 | 数据范畴

业务域、主题域咱们都能够用词根的形式枚举分明,不断完善。

更新周期次要的是工夫粒度、日、月、年、周等。

2) 两头表

两头表个别呈现在 Job 中,是 Job 中长期存储的两头数据的表,两头表的作 用域只限于以后 Job 执行过程中,Job 一旦执行实现,该两头表的使命就完 成了,是能够删除的(依照本人公司的场景自由选择,以前公司会保留几天 的两头表数据,用来排查问题)。

标准:mid_table_name_[0~9|dim]

table_name 是咱们工作中指标表的名字,通常来说一个工作只有一个指标表。
这里加上表名,是为了避免自由发挥的时候表名抵触,而开端大家能够抉择自由发挥,起一些有意义的名字,或者简略粗犷,应用数字代替,各有优劣吧,审慎抉择。

通常会遇到须要补全维度的表,这里应用 dim 结尾。

如果要保留历史的两头表,能够加上日期或者工夫戳。

3) 长期表

长期表是长期测试的表,是长期应用一次的表,就是临时保留下数据看看,后续个别不再应用的表,是能够随时删除的表。

标准:tmp_xxx

只有加上 tmp 结尾即可,其余名字随便,留神 tmp 结尾的表不要用来理论应用,只是测试验证而已。

4) 维度表

维度表是基于底层数据,形象进去的形容类的表。维度表能够主动从底层表形象进去,也能够手工来保护。

标准:dim_xxx

维度表,对立以 dim 结尾,前面加上,对该指标的形容。

5) 手工表

手工表是手工保护的表,手工初始化一次之后,个别不会主动扭转,前面变更,也是手工来保护。

一般来说,手工的数据粒度是偏细的,所以临时对立放在 dwd 层,前面如果有目标值或者其余类型手工数据,再依据理论状况分层。

标准:dwd_业务域_manual_xxx

手工表,减少非凡的主题域,manual,示意手工保护表。

3. 指标命名标准

公共规定
  • 所有单词小写
  • 单词之间下划线宰割(反例:appName 或 AppName)
  • 可读性优于长度 (词根,避免出现同一个指标,命名一致性)
  • 禁止应用 sql 关键字,如字段名与关键字抵触时 +col
  • 数量字段后缀 _cnt 等标识 …
  • 金额字段后缀 _price 标识
  • 天分区应用字段 dt,格局对立(yyyymmdd 或 yyyy-mm-dd)
  • 小时分区应用字段 hh,范畴(00-23)
  • 分钟分区应用字段 mi,范畴(00-59)
  • 布尔类型标识:is_{业务},不容许呈现空值

参考文档:

  1. 上百本优质大数据书籍,附必读清单(大数据宝藏)
  2. 最强最全面的数仓建设标准指南
  3. 美团数据平台及数仓建设实际,超十万字总结
  4. 五万字 | 耗时一个月整顿出这份 Hadoop 吐血宝典

正文完
 0