精华内容
下载资源
问答
  • 在数据清单中的行代表
    2021-05-01 12:31:30

    1. 建模流程

    1. 确认主题域边界,明确业务范围。
    2. 根据业务范围,拆分由业务专家认可的最细粒度业务过程(比如投保->承保->…)
    3. 识别业务过程中的实体,可以结合人货场与实体建模法的方法,确定其流程中的主实体和其他实体。
    4. 确定粒度(粒度,一行数据代表:一条保单?一条批单?一天的保费?),将主实体相关属性作为设计事实表(单/多事务事实表、单维度/混合维度/全量周期快照事实表,累积快照事实表) 度量的依据。
    5. 确定维度,将其他实体作为维度,如who?when?where?
    6. 将常用维度退化至事实表中

    2. 迭代流程

    根据需求迭代:

    1. 事实表关联实体清单:按需添加相关的实体;
    2. 在事实表中按需添加属性和维度;

    3. 主题域划分

    主题域划分具体分为4步:

    1. 业务系统功能模块梳理
      为了建设比较全面的调研框架,需要基于已经沉淀的业务系统,来设计调研内容。理论上一个业务系统中所有的功能模块肯定是业务运行过程中需要使用的或者说曾经需要使用的,而且功能模块设计就能够串起整个主线流程,将每个模块下支持的哪些功能梳理清楚,通过功能模块先建立其骨架。
    2. 业务动作梳理
      了解维持正常业务运行时,是哪些人需要展开哪些业务活动,存在哪些度量和需要量化的数据,其业务活动的粒度要到最细不可拆分的粒度,串起整个业务运行的全景图。
    3. 业务调研
      有了全业务流程图,还需要明确业务方期望了解哪些信息,同时需要明确最细粒度的业务动作,业务动作的组合,业务动作发生后的状态,汇聚成最终的业务过程。
    4. 划分数据域
      按照两个原则一个思想来设计数据域,将所有的业务过程进行聚类,高度抽象后形成数据域。
      • 第一原则:高内聚低耦合,将概念接近,关联度高的放在一类。
      • 第二原则:保证抽象逻辑的一致性,形成最终的数据域和相关业务过程。
      • 一个思想:螺旋递进,数据域的划分没有完美的状态,只有接近完美,在实践过程中以螺旋递进的方式记性迭代优化。
        注:
        常见的抽象方法:
      1. 按照业务或业务过程划分:比如一个靠销售广告位置的门户网站主题域可能会有广告域,客户域等,而广告域可能就会有广告的库存,销售分析、内部投放分析等主题。
      2. 根据需求方划分:比如需求方为财务部,就可以设定对应的财务主题域,而财务主题域里面可能就会有员工工资分析,投资回报比分析等主题;
      3. 按照功能或应用划分:比如微信中的朋友圈数据域、群聊数据域等,而朋友圈数据域可能就会有用户动态信息主题、广告主题等;
      4. 按照部门划分:比如可能会有运营域、技术域等,运营域中可能会有工资支出分析、活动宣传效果分析等主题。

    4. 业务建模

    在梳理业务过程中,我们如何快速的去理解业务,构建领域概念模型。通常我们采用实体建模法。

    4.1 实体建模法

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

    虽然实体法看起来好像有一些抽象,其实理解起来很容易。即我们可以将任何一个业务过程划分成3个部分,实体,事件和说明。举个栗子,小明早上骑自行车去上学校。其中实体:小明,学校,存在的关系为:小明是学校的学生,说明:小明是在早上通过骑行车去上的学。

    5. 维度表

    5.1 维度表的定义

    • 维度表定义:一般是对事实的描述信息,每一张维度表对应现实世界中的一个对象或者概念。例如:用户、商品、日期、地区等。

    注意:如果属性值是离散的,用于过滤和标记的,就放到维度表里,如果是属性值是连续取值,可用于计算的,就放到事实表中。

    • 维度表的特征:
    1. 维度表的范围很宽(具有多个属性、列比较多)
    2. 跟事实表相比,行数较少,(通常小于10万条)
    3. 内容相对固定

    5.2 维表的类型

    1. 缓慢变化维

      • 类型一:字段值发生变化时覆盖原来的值。
      • 类型二:字段值发生变化时会新增一行,重新分配代理键。
      • 类型三:每条记录会新增一列来标识变化前的值,发生变化时,把旧值放到新增的列中,把新值覆盖旧值。
    2. 日期维

      • 它是数据仓库必须有的维度,包含日期,日期所属的周,月,季度,年等信息。
    3. 角色维

      • 相同的维度表在维度模型中扮演不同的逻辑角色,一般通过创建视图来表示。
    4. 杂项维

      • 如果每个属性值都很少,可以把这些维度组合起来,生成一个维度表。
    5. 支架维

      • 如果维度之间是一对多的关系或区别于原维度的多个描述性维度属性,可以建立雪花支架维度
        (图1)
    6. 多值维度桥接维

      • 如果两个维度表是多对多的关系,可以使用多值维度设计。
        (图2)
    7. 微型维

      • 一个大型维有些属性变化比较频繁,把这些属性单独生成一个微型维度表。
        (图3)
    8. 缩小维

      • 它是维度表的一个子集或部分属性
    9. 查找维

      • 系统代码表里维度的信息
    10. 层级维

      • 有些维度表是有层级结构的,可以通过视图生成树形结构的维度表
        (图4)
    11. 手工维护的维表

      • 有些数据不再业务系统里,需要业务用户手工维护的维度表。

    5.3 维度表设计原则

    • 一致性维度

    数据仓库中维度表的一致性,其实一致性维度在表结构和属性都没有本质的区别,有一点的差异是数据仓库的星型模型会使得维度表有一定的冗余。那么一致性体现在哪里呢:维度共享性。共享性体现在整个平台或整个部门共用维度,而不仅仅只是单纯某个业务单独使用。

    一般的维度并没有把共享性作为一个共性的标准。然而在维度建模中,一致性维度将作为重心来做。数据仓库70%的工作量和复杂度是用在构建一致性维度。

    6. 事实表

    • 事实表定义:表中的每行数据代表一个业务事件(如投保,理赔),事实表示的是业务事件的度量值(可以统计次数、个数、金额等),例如缴费事件中的支付金额。
      每一行事实表的数据包括:具有可加性的数值型的度量值、与维度表相连接的外键,通常具有两个及以上的外键。

    • 事实表的特征:
      1.行多列少
      2.经常发生变化,每天新增很多

    • 一致性事实

    指每个度量在整个数据仓库中都是唯一的统计口径,为了避免歧义,一个度量只有唯一的业务术语。一致性事实和一致性维度有些不同,一致性维度是由专人维护在后台,发生修改时同步复制到每个数据集市,而事实表一般不会在多个数据集市间复制。需要查询多个数据集市中的事实时,一般通过交叉探查来实现。为了能在多个数据集市间进行交叉探查,一致性事实主要需要保证两点。第一个是KPI的定义及计算方法要一致,第二个是事实的单位要一致性。

    • 事实表分类:

    在Kimball的维度建模理论中主要定义了事务事实表、周期快照事实表、累积快照事实表三种类型的事实表

    1. 事务事实表: 描述业务过程事务层面的事实,每条记录代表一个事务事件,保留事务事件活动的原始内容

      事务事实表中的数据在事务事件发生后记录,一般记录后数据就不再进行更改,其更新方式为增量更新;

    2. 周期快照事实表:以具有规律性时间间隔生成快照来记录事实,每行代表某个时间周期的一条记录,记录的事实是时间周期内的汇总度量值。
      周期快照事实表的内容一般在所表达的时间周期结束后才会产生, 一般记录后数据就不再更改,其更新方式为增量更新。周期快照事实表一般是建立在事务事实表之上的汇聚,维度比事务事实表少,粒度比事务事实表粗,不同时间周期的也会生成多个周期快照事实表。如月(季)度销售报表。

    3. 累计快照事实表: 每行记录一个流程从开始到结束、全生命周期的所有关键节点,通常具有多个日期字段来记录关键事件时间点。

      对于不同过程,要设计统一的结束标志,没有的业务时间置空。有时需要将每个过程时间间隔作为事实放在表中,如:报案至查勘时间间隔等。

      累计快照事实表涉及的多个度量中任意一个的变化都要做记录, 由于周期快照事实表涉及的多个事件的首次加载和后续更新时间是不确定的,因此在首次加载后允许对记录进行更新。这里分三种情况:

      1. 全量表:一般是日分区,每天存储前一天的全量数据和当天增量(更新)数据进行合并,保证每条数据的最新状态,此方式适用于数据量不大的情况。
      2. 全量变化表:累积事实表用于保存生命周期短的实例,所以可以根据业务实体从开始到结束的最大时间间隔,如交易业务最大时间跨度200天,每天保存的是过去200天的全量数据,200天之前的数据存储在归档表中。适用于数据量大的场景。
      3. 以业务结束时间分区:每天分区中存放的是当天结束的业务,然后用一个非常大的分区(如 3000-12-31)保存所有至今未结束的记录,这种方式不会浪费存储资源。
    比较项事务事实表周期快照事实表累积快照事实表
    代表的时间段离散的时间点记录事务规律性的间隔不确定时间跨度且不断变化的业务事实
    粒度每行代表一个事务每行代表周期时间内的聚集事务值每行代表一个流程的全生命周期
    事实表加载insertinsertinsert & update
    事实表更新不重新加载不重新加载行为发生任何时候都要重新加载
    日期维度事务日期时间段终止日期关键节点的多个日期

    6.1 事实表设计原则

    1. 尽可能包含所有与业务过程相关的事实

    事实表设计的目的是为了度量业务过程,所以分析哪些事实与业务过程有关是设计中非常重要的关注点。在事实表中应该尽量包含所有与业务过程相关的事实,即使存在冗余,但是因为事实通常为数字型,带来的存储开销也不会很大。

    1. 只选择与业务过程相关的事实

    在选择事实,应该注意只选择与业务过程有关的事实。比如在订单的下单这个业务过程的事实表设计中 ,不应该存在支付金额这个表示支付业务过程的事实。

    1. 分解不可加事实为可加的组件

    对于不具备可加性条件的度量,需要分解为可加的度量。比如订单的优惠率,应该分解为订单原价金额与订单优惠金额两个事实存储在事实表中。

    1. 在选择维度和事实之前必须先生声明粒度

    粒度的声明是事实表设计中不可忽视的重要一步,粒度用于确定事实表中一行所表示业务的细节层次,决定了维度模型的扩展性,在选择维度和事实之前必须先声明粒度,且每个维度和事实必须与所定义的粒度保持一致。在设计事实表的过程中,粒度定义得越细越好,建议从最低级别的原子粒度开始,因为原子粒度提供了最大限度的灵活性(比如订单粒度无法统计商品粒度的值),可以支持无法预期的各种细节层次的用户需求。在事实表中,通常通过业务描述来表述粒度,但对于聚集性事实表的粒度描述,可采用维度或维度属性组合的方式。

    1. 在同一个事实表中不能同时存在多种不同粒度的事实

    事实表中的所有事实需要与表定义的粒度保持一致,在同个事务表中不能有多种不同粒度的事实。不然对不同粒度的事实进行累加时,其实是会出现很大问题的。

    1. 事实的单位要保持一致

    对于同 个事实表中事实的单位,应该保持一致。比如原订单金额、订单优惠金额、订单运费金额这三个事实,应该采用一致的计量单位,统一为元或分,以方便使用。

    1. 对事实的null值要处理

    对于事实表中事实度量为 null 值的处理,因为在数据库中null对常用数字型字段的 SQL 过滤条件都不生效,比如大于、小于、等于、大于或等于、小于或等于,建议用-9999填充。

    1. 使用退化维度提高事实表的易用性

    在Kimball的维度建模中,通常按照星形模型的方式来设计,对于维度的获取采用的是通过事实表的外键关联专门的维表的方式,谨慎使用退化维度。而在大数据领域的事实表设计中,则大量采用退化维度的方式,在事实表中存储各种类型的常用维度信息。这样设计的目的主要是为了减少下游用户使用时关联多个表的操作,直接通过退化维度实现对事实表的过滤查询、控制聚合层次、排序数据以及定义主从关系等。 通过增加冗余存储的方式减少计算开销,提高使用效率。

    7. 维度建模的缺点

    • 维度建模之前需要进行大量的数据预处理,因此会导致大量的数据处理工作(ETL)。
    • 当业务发生变化,需要重新进行维度的定义时,往往需要重新进行维度数据的预处理。而在这些与处理过程中,往往会导致大量的数据冗余。
    • 如果只是依靠单纯的维度建模,不能保证数据来源的一致性和准确性,还需要对业务元数据,技术元数据进行口径统一,才可保证一致性和准确性,
    • 而且在数据仓库的底层,不是特别适用于维度建模的方法。

    8.维度建模和宽表的适用場景

    8.1 维度建模

    维度建模主要适用于dwd层的建设,它的最大的作用其实是为了解决数据仓库建模中的性能问题。维度建模很难能够提供一个完整地描述真实业务实体之间的复杂关系的抽象方法。

    8.2 宽表

    宽表的使用主要适用于数据集市层的建设,

    1. 根据主题域和业务域,将某个业务线的所有业务过程梳理清楚;

    2. 将被业务认可的最细粒度的业务过程的数据作为事实表依据,然后横向扩充其他事实表上卷数据(包含一些统计指标),同时纵向的添加该业务过程中一些主键对应的维度;

    3. 宽表的设计不依赖具体的业务需求而是根据整体业务线相匹配;

    4. 维度模型可以作为宽表的基础,一旦确定全部的数据链路,可以通过维度模型再生成对应宽表进行快速的业务支撑;

    比较项维度建模宽表
    扩展性维度表变更,事实表可能不影响维度变更可能导致很多宽表都要调整
    耦合度事实表和维度表解藕,某些粒度上不会因为维度表失败而影响聚合表的产出一个非重要任务失败会导致整个宽表无法产出
    组织方式任务及工作流易组织因高耦合导致任务之间盘根错节,不利于组织任务和工作流
    数据一致性企业级数据仓库总线架构的基石底层如果没有维度建模支撑,容易陷入混乱
    易用性事务日期时间段终止日期

    9. 数仓经验

    数仓设计是有别于传统的业务系统的三范式设计方法的。这里暂时不讨论Inmon和Kimball两位大神设计理念的异同,只从实际工作中来讲。

    • 针对主数据,核心维度,是用缓慢变化维中的哪种设计方法。
      请避免使用拉链表,建议改成全量快照表,主要原因在于很多时候需要回刷历史数据。

    • 如何规避上游模型完成过晚问题?
      如果对数据准确度要求没有特别高,请使用T-2分区数据
      如果对数据准确度较高,请先建一张未来分区的全量快照表(如3000-12-31),下游应用直接定点依赖该表。这样的好处在于如果到点,当天的数据已经跑完,则用当前分区数据,反之用T-2数据。

    • 维度过多,算不出来
      用好 grouping sets。多维分析的基础,极大的节省olap工具的算力,代码简洁了很多,并且生成的job数也变少且计算的效率提高了(UNION ALL是多次扫描表)

    • 数据变化过快
      用好复杂结构,尤其是map,尤其是在对大量页面的PV,UV计算中,因为业务发展太快,页面上了一个又一个,其变化速度远大于模型修改的速度,因为要把模型设计的更灵活。

    更多相关内容
  • 谈数仓之前,先来看下面几个问题:数仓为什么要分层?用空间换时间,通过大量的预处理来提升应用系统的用户体验(效率),因此数据仓库会存在大量冗余的数据;不分层的话,如果源业务系统的业务规则发生变化将会...

    进入主页,点击右上角“设为星标”

    比别人更快接收好文章


    本文分为两大节介绍,第一节是数仓建设,第二节是数据治理,内容较长,还请耐心阅读!

    在谈数仓之前,先来看下面几个问题:

    数仓为什么要分层?

    1. 用空间换时间,通过大量的预处理来提升应用系统的用户体验(效率),因此数据仓库会存在大量冗余的数据;不分层的话,如果源业务系统的业务规则发生变化将会影响整个数据清洗过程,工作量巨大。

    2. 通过数据分层管理可以简化数据清洗的过程,因为把原来一步的工作分到了多个步骤去完成,相当于把一个复杂的工作拆成了多个简单的工作,把一个大的黑盒变成了一个白盒,每一层的处理逻辑都相对简单和容易理解,这样我们比较容易保证每一个步骤的正确性,当数据发生错误的时候,往往我们只需要局部调整某个步骤即可。

    数据仓库之父 Bill Inmon对数据仓库做了定义——面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。从定义上来看,数据仓库的关键词为面向主题、集成、稳定、反映历史变化、支持管理决策,而这些关键词的实现就体现在分层架构内。

    一个好的分层架构,有以下好处:

    1. 清晰数据结构:每一个数据分层都有对应的作用域,在使用数据的时候能更方便的定位和理解。

    2. 数据血缘追踪:提供给业务人员或下游系统的数据服务时都是目标数据,目标数据的数据来源一般都来自于多张表数据。若出现目标数据异常时,清晰的血缘关系可以快速定位问题所在。而且,血缘管理也是元数据管理重要的一部分。

    3. 减少重复开发:数据的逐层加工原则,下层包含了上层数据加工所需要的全量数据,这样的加工方式避免了每个数据开发人员都重新从源系统抽取数据进行加工。

    4. 数据关系条理化:源系统间存在复杂的数据关系,比如客户信息同时存在于核心系统、信贷系统、理财系统、资金系统,取数时该如何决策呢?数据仓库会对相同主题的数据进行统一建模,把复杂的数据关系梳理成条理清晰的数据模型,使用时就可避免上述问题了。

    5. 屏蔽原始数据的影响:数据的逐层加工原则,上层的数据都由下一层的数据加工获取,不允许跳级取数。而原始数据位于数仓的最底层,离应用层数据还有多层的数据加工,所以加工应用层数据的过程中就会把原始数据的变更消除掉,保持应用层的稳定性。

    数仓分几层最好?

    目前市场上主流的分层方式眼花缭乱,不过看事情不能只看表面,还要看到内在的规律,不能为了分层而分层,没有最好的,只有适合的。

    分层是以解决当前业务快速的数据支撑为目的,为未来抽象出共性的框架并能够赋能给其他业务线,同时为业务发展提供稳定、准确的数据支撑,并能够按照已有的模型为新业务发展提供方向,也就是数据驱动和赋能。

    如何搭建一个好的数仓?

    1. 稳定:数据产出稳定且有保障。

    2. 可信:数据干净、数据质量高。

    3. 丰富:数据涵盖的业务足够广泛。

    4. 透明:数据构成体系足够透明。

    数仓设计

    数仓设计的3个维度:

    • 功能架构:结构层次清晰。

    • 数据架构:数据质量有保障。

    • 技术架构:易扩展、易用。

    数仓架构

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

    475cda9b81146d211cc7cc396bb8f264.png
    数据仓库

    数据仓库的数据来源于不同的源数据,并提供多样的数据应用,数据自下而上流入数据仓库后向上层开放应用,而数据仓库只是中间集成化数据管理的一个平台。

    源数据:此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。

    数据仓库:也称为细节层,DW层的数据应该是一致的、准确的、干净的数据,即对源系统数据进行了清洗(去除了杂质)后的数据。

    数据应用:前端应用直接读取的数据源;根据报表、专题分析需求而计算生成的数据。

    数据仓库从各数据源获取数据及在数据仓库内的数据转换和流动都可以认为是ETL(抽取Extra, 转化Transfer, 装载Load)的过程,ETL是数据仓库的流水线,也可以认为是数据仓库的血液,它维系着数据仓库中数据的新陈代谢,而数据仓库日常的管理和维护工作的大部分精力就是保持ETL的正常和稳定。

    建设数据仓库犹如创造一条新的生命,分层架构只是这条生命的逻辑骨架而已。想要在骨架上长出血肉,就必须进行合适的数据建模,数据仓库的强壮还是孱弱,健美还是丑陋,就取决于建模的结果。

    数仓建模方法

    数据仓库的建模方法有很多种,每一种建模方法代表了哲学上的一个观点,代表了一种归纳、概括世界的一种方法。常见的有 范式建模法、维度建模法、实体建模法等,每种方法从本质上将是从不同的角度看待业务中的问题。

    1. 范式建模法

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

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

    在数据仓库的模型设计中,一般采用第三范式。一个符合第三范式的关系必须具有以下三个条件 :

    • 每个属性值唯一,不具有多义性 ;

    • 每个非主属性必须完全依赖于整个主键,而非主键的一部分 ;

    • 每个非主属性不能依赖于其他关系中的属性,因为这样的话,这种属性应该归到其他关系中去。

    6d743ec58e9f3b96c415884750b1d200.png
    范式建模

    根据 Inmon 的观点,数据仓库模型的建设方法和业务系统的企业数据模型类似。在业务系统中,企业数据模型决定了数据的来源,而企业数据模型也分为两个层次,即主题域模型和逻辑模型。同样,主题域模型可以看成是业务模型的概念模型,而逻辑模型则是域模型在关系型数据库上的实例化。

    2. 实体建模法

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

    虽然实体法粗看起来好像有一些抽象,其实理解起来很容易。即我们可以将任何一个业务过程划分成 3 个部分,实体,事件,说明,如下图所示:

    2bfc042b519e8d83ee2208f481246b87.png
    实体建模

    上图表述的是一个抽象的含义,如果我们描述一个简单的事实:“小明开车去学校上学”。以这个业务事实为例,我们可以把“小明”,“学校”看成是一个实体,“上学”描述的是一个业务过程,我们在这里可以抽象为一个具体“事件”,而“开车去”则可以看成是事件“上学”的一个说明。

    3. 维度建模法

    维度模型是数据仓库领域另一位大师Ralph Kimall所倡导,他的《数据仓库工具箱》是数据仓库工程领域最流行的数仓建模经典。维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,因此它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能。

    99697f08865043585466f6ffb910ceb4.png
    星形模型

    典型的代表是我们比较熟知的星形模型(Star-schema),以及在一些特殊场景下适用的雪花模型(Snow-schema)。

    维度建模中比较重要的概念就是 事实表(Fact table)和维度表(Dimension table)。其最简单的描述就是,按照事实表、维度表来构建数据仓库、数据集市。

    目前在互联网公司最常用的建模方法就是维度建模。

    维度建模怎么建:

    在实际业务中,给了我们一堆数据,我们怎么拿这些数据进行数仓建设呢,数仓工具箱作者根据自身60多年的实际业务经验,给我们总结了如下四步。

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

    fb716840f86dfe43871d857cb1ebe097.png
    维度建模四步走

    这四步是环环相扣,步步相连。下面详细拆解下每个步骤怎么做

    1、选择业务过程

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

    2、声明粒度

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

    3、确认维度

    • 维度表是作为业务分析的入口和描述性标识,所以也被称为数据仓库的“灵魂”。在一堆的数据中怎么确认哪些是维度属性呢,如果该列是对具体值的描述,是一个文本或常量,某一约束和行标识的参与者,此时该属性往往是维度属性,数仓工具箱中告诉我们牢牢掌握事实表的粒度,就能将所有可能存在的维度区分开,并且要确保维度表中不能出现重复数据,应使维度主键唯一

    4、确认事实

    • 事实表是用来度量的,基本上都以数量值表示,事实表中的每行对应一个度量,每行中的数据是一个特定级别的细节数据,称为粒度。维度建模的核心原则之一是同一事实表中的所有度量必须具有相同的粒度。这样能确保不会出现重复计算度量的问题。有时候往往不能确定该列数据是事实属性还是维度属性。记住最实用的事实就是数值类型和可加类事实。所以可以通过分析该列是否是一种包含多个值并作为计算的参与者的度量,这种情况下该列往往是事实。

    其中粒度是非常重要的,粒度用于确定事实表的行表示什么,建议从关注原子级别的粒度数据开始设计,因为原子粒度能够承受无法预估的用户查询,而且原子数据可以以各种可能的方式进行上卷,而一旦选择了高粒度,则无法满足用户下钻细节的需求。

    事实是整个维度建模的核心,其中雪花模型或者星型模型都是基于一张事实表通过外健关联维表进行扩展,生成一份能够支撑可预知查询需求的模型宽表,而且最后的查询也是落在事实表中进行。

    实际业务中数仓分层

    数仓分层要结合公司业务进行,并且需要清晰明确各层职责,要保证数据层的稳定又要屏蔽对下游影响,一般采用如下分层结构:

    80b57b36a7dcbda11252d56c0aac9867.png
    数据分层架构

    数据层具体实现

    使用四张图说明每层的具体实现

    • 数据源层ODS

    e37ee45c164974c9fdf550f5e5d5a32d.png
    数据源层

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

    • 数据明细层DW

    45909c207264c4e8633b55b875900025.png
    数据明细层

    事实表中的每行对应一个度量,每行中的数据是一个特定级别的细节数据,称为粒度。维度建模的核心原则之一是同一事实表中的所有度量必须具有相同的粒度。这样能确保不会出现重复计算度量的问题。

    维度表一般都是单一主键,少数是联合主键,注意维度表不要出现重复数据,否则和事实表关联会出现数据发散问题。

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

    • 数据轻度汇总层DM

    e9802a330f5563623b72710584579e72.png
    数据轻度汇总层

    此层命名为轻汇总层,就代表这一层已经开始对数据进行汇总,但是不是完全汇总,只是对相同粒度的数据进行关联汇总,不同粒度但是有关系的数据也可进行汇总,此时需要将粒度通过聚合等操作进行统一。

    • 数据应用层APP

    4da383fe456c261325dfabbe40f3a639.png
    数据应用层

    数据应用层的表就是提供给用户使用的,数仓建设到此就接近尾声了,接下来就根据不同的需求进行不同的取数,如直接进行报表展示,或提供给数据分析的同事所需的数据,或其他的业务支撑。

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

    26b7a886fe18f3983152ebc1f5dad4d1.png
    数仓整体流程

    数据治理

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

    其实数据治理的范围很⼴,包含数据本⾝的管理、数据安全、数据质量、数据成本等。在DAMA 数据管理知识体系指南中,数据治理位于数据管理“车轮图”的正中央,是数据架构、数据建模、数据存储、数据安全、数据质量、元数据管理、主数据管理等10大数据管理领域的总纲,为各项数据管理活动提供总体指导策略。

    e0592114212a5a9dd8a478e680c57b95.png

    数据治理之道是什么

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

    为发挥数据价值需要满足三个要素:合理的平台架构、完善的治理服务、体系化的运营手段

    根据企业的规模、所属行业、数据量等情况选择合适的平台架构;治理服务需要贯穿数据全生命周期,保证数据在采集、加工、共享、存储、应用整个过程中的完整性、准确性、一致性和实效性;运营手段则应当包括规范的优化、组织的优化、平台的优化以及流程的优化等等方面。

    2. 数据治理需要夯实基础

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

    3. 数据治理需要IT赋能

    数据治理不是一堆规范文档的堆砌,而是需要将治理过程中所产生的的规范、流程、标准落地到IT平台上,在数据生产过程中通过“以终为始”前向的方式进行数据治理,避免事后稽核带来各种被动和运维成本的增加。

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

    数据治理的本质是管理数据,因此需要加强元数据管理和主数据管理,从源头治理数据,补齐数据的相关属性和信息,比如:元数据、质量、安全、业务逻辑、血缘等,通过元数据驱动的方式管理数据生产、加工和使用。

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

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

    浅谈数据治理方式

    如上面所说,数据治理的范围非常广,其中最重要的是数据质量治理,而数据质量涉及的范围也很广,贯穿数仓的整个生命周期,从数据产生->数据接入->数据存储->数据处理->数据输出->数据展示,每个阶段都需要质量治理,评价维度包括完整性、规范性、一致性、准确性、唯一性、关联性等。

    在系统建设的各个阶段都应该根据标准进行数据质量检测和规范,及时进行治理,避免事后的清洗工作。

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

    维度衡量标准
    完整性业务指定必须的数据是否缺失,不允许为空字符或者空值等。例如,数据源是否完整、维度取值是否完整、数据取值是否完整等
    时效性当需要使用时,数据能否反映当前事实。即数据必须及时,能够满足系统对数据时间的要求。例如处理(获取、整理、清洗、加载等)的及时性
    唯一性在指定的数据集中数据值是否唯一
    参照完整性数据项是否在父表中有定义
    依赖一致性数据项取值是否满足与其他数据项之间的依赖关系
    正确性数据内容和定义是否一致
    精确性数据精度是否达到业务规则要求的位数
    技术有效性数据项是否按已定义的格式标准组织
    业务有效性数据项是否符合已定义的
    可信度根据客户调查或客户主动提供获得
    可用性数据可用的时间和数据需要被访问时间的比例
    可访问性数据是否便于自动化读取

    下面是根据美团的技术文章总结的几点具体治理方式:

    1. 规范治理

    规范是数仓建设的保障。为了避免出现指标重复建设和数据质量差的情况,统一按照最详细、可落地的方法进行规范建设。

    (1) 词根

    词根是维度和指标管理的基础,划分为普通词根与专有词根,提高词根的易用性和关联性。

    • 普通词根:描述事物的最小单元体,如:交易-trade。

    • 专有词根:具备约定成俗或行业专属的描述体,如:美元-USD。

    (2) 表命名规范

    通用规范

    • 表名、字段名采用一个下划线分隔词根(示例:clienttype->client_type)。

    • 每部分使用小写英文单词,属于通用字段的必须满足通用字段信息的定义。

    • 表名、字段名需以字母为开头。

    • 表名、字段名最长不超过64个英文字符。

    • 优先使用词根中已有关键字(数仓标准配置中的词根管理),定期Review新增命名的不合理性。

    • 在表名自定义部分禁止采用非标准的缩写。

    表命名规则

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

    4a5fd5c8524a27dde3d8df31e9a0c83a.png
    统一的表命名规范

    (3) 指标命名规范

    结合指标的特性以及词根管理规范,将指标进行结构化处理。

    1. 基础指标词根,即所有指标必须包含以下基础词根:

    40cfa54d236fbf10538e21c7f97a7de8.png
    1. 业务修饰词,用于描述业务场景的词汇,例如trade-交易。

    3.日期修饰词,用于修饰业务发生的时间区间。

    1f4be8cdb6becb7e3457fcd6bbc9d16f.png

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

    1d0bc587793d10cd5177d5074a5402c9.png

    5.基础指标,单一的业务修饰词+基础指标词根构建基础指标 ,例如:交易金额-trade_amt。

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

    7.普通指标命名规范,与字段命名规范一致,由词汇转换即可以。88ecf7f54e46e6eaec79f18662a00c69.png

    2. 架构治理

    (1) 数据分层

    优秀可靠的数仓体系,往往需要清晰的数据分层结构,即要保证数据层的稳定又要屏蔽对下游的影响,并且要避免链路过长,一般的分层架构如下:dc2a2a3d2cf90b0e50df03bd77261559.png

    (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. 数据生命周期治理

    任何事物都具有一定的生命周期,数据也不例外。从数据的产生、加工、使用乃至消亡都应该有一个科学的管理办法,将极少或者不再使用的数据从系统中剥离出来,并通过核实的存储设备进行保留,不仅能够提高系统的运行效率,更好的服务客户,还能大幅度减少因为数据长期保存带来的储存成本。数据生命周期一般包含在线阶段、归档阶段(有时还会进一步划分为在线归档阶段和离线归档阶段)、销毁阶段三大阶段,管理内容包括建立合理的数据类别,针对不同类别的数据制定各个阶段的保留时间、存储介质、清理规则和方式、注意事项等。

    8be9e06aee4c4c254285e4ea49535792.png

    从上图数据生命周期中各参数间的关系中我们可以了解到,数据生命周期管理可以使得高价值数据的查询效率大幅提升,而且高价格的存储介质的采购量也可以减少很多;但是随着数据的使用程度的下降,数据被逐渐归档,查询时间也慢慢的变长;最后随着数据的使用频率和价值基本没有了之后,就可以逐渐销毁了。

    28348dd5cfe7cb8471ba59e47a1b2f64.gif

    干货直达👇

    更多精彩👇

    展开全文
  • 该视频,我们以王大爷的需求为例: M5 超级问卷星名称的由来 M5 来源于基于 ESP32 的 M5core2 开发板,问卷星代表它是一个问卷调查表格统计类设备,正如前几期分享的 M5 Server X 一样,它们同属于网络服务器的...

    b7f76c86fa762887f9f81b94a4b54e3d.png

    1cfc11574ee4187e8b7fc69829511ce9.png

    作者:默

    不知不觉疫情已持续 3 年了,最近门卫王大爷很苦恼,因为领导要求所有进入单位的人员与车辆按照防疫要求进行登记,登记的内容有来访人员的车牌号、姓名、性别、体温、联系电话、被访人及其进入单位的时间 等。大爷年纪大了,有些时候记性也不太好,登记时经常会卡壳,每次都要向来访人员询问老半天,后面来访的人员看着不知所措的王大爷也有些无奈,毕竟大爷就是你大爷,又不能催促,只能老老实实排队等待了。大爷自己也发现了这个问题,于是就找到我,想让我给他出出主意,想一个好办法来解决他现在的问题,提高他的工作效率。

    在一些小区和医院等场合,笔者也发现了和王大爷相似的情况:

    • 小区保安需要登记来访人员与车辆;

    • 医院服务的大白与志愿者们需要登记来院所有人员的家庭住址、身份证号、近期外出情况等信息;

    • 临近假期,某些大学辅导员们也要登记学生假期安排情况(留校或回家)。

    这些问题都有一个共同的特点:那就是都属于表格统计,仅有简单的文本类信息,传统的这类信息录入都是靠打印纸质表格由相关人员逐一填写,费时费力,遇到问题需要查找某个人员相关信息时,都要从大量的纸质表格中去检索信息,这种古老而传统的方式在数字化的今天无疑是十分落后的。作为实用型 Maker 的我,针对这些痛点问题,我开发了“M5 超级问卷星”这个项目,通过在线的方式将数据进行录入,并且支持在线搜索与查看,以及将数据导出为 Excel 表格。

    下面让我们先来看看这个项目的演示视频。该视频中,我们以王大爷的需求为例:

    M5 超级问卷星名称的由来

    M5 来源于基于 ESP32 的 M5core2 开发板,问卷星代表它是一个问卷调查表格统计类设备,正如前几期分享的 M5 Server X 一样,它们同属于网络服务器的范畴,故名 M5 超级问卷星。运用 M5 超级问卷星,我们能够将任何文本类数据进行在线收集,并在线查看与导出 Excel 表格,例如防疫登记表、离校意向表、商品出售清单等,农林或生物系学生可以将它用来记录一些对照试验的表格,当然 M5 超级问卷星能做的还有很多,只要有表格的地方都会有它的用武之地。

    预期目标及功能

    • 在线提交表单数据

    • 数据提交反馈

    • 在线数据查看

    • 在线数据检索

    • 在线数据导出为 Excel 表格

    • SD 卡配置文件加载

    • 二维码显示服务网址

    所用硬件

    • M5 Core2

    aa825802c38e32eb8a845ba62cbd68ff.png

    M5Core2特点

    • 基于 ESP32 开发,支持 WiFi、蓝牙;

    • 16 M 闪存,8 M PSRAM;

    • 内置扬声器,电源指示灯,震动马达,RTC,I2S 功放,电容式触摸屏,电源键,复位键;

    • TF 卡插槽(支持最大 16GB);

    • 内置锂电池,配备电源管理芯片;

    • 独立小板内置 6 轴 IMU,PDM 麦克风;

    • M-Bus 总线插座。

    程序设计

    下面开始详细讲解程序设计过程。

    开发环境

    我们使用 Aduino IDE 软件来编写本项目的程序,开发板选择 M5Stack-Core2。至于如何在 Arduino 中配置 ESP32 的开发环境,不在本文的介绍范围,请自行查阅相关资料。

    程序思路

    为了达到我们的预期目标,我们先绘制功能的思维导图,再根据思维导图逐步实现 M5 超级问卷星的程序设计。

    ad647e8792f93ff9dd6f08c8cc933cdc.png

    下面我们将具体讨论 M5 超级问卷星各个子功能是如何实现的。

    获取提交参数

    在前期 M5 Server  X 项目中我们采用构造路径参数的方式来区分每个服务,本期我们将采用请求参数的方式获取来自网页表单的数据,示例如下。

    #include <WiFi.h>
    #include <FS.h>
    #include <AsyncTCP.h>
    #include <ESPAsyncWebServer.h>
    
    const char* ssid = "xxxxxx";
    const char* password = "xxxxxx";
    
    AsyncWebServer server(80);
    
    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi..");
      }
    
      Serial.println(WiFi.localIP());
      server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
        int paramsNr = request->params();//获取提交参数的个数
        Serial.println(paramsNr);
        for (int i = 0; i < paramsNr; i++) {//循环打印所有提交参数
          AsyncWebParameter* p = request->getParam(i);
          Serial.print("Param name: ");
          Serial.println(p->name());
          Serial.print("Param value: ");
          Serial.println(p->value());
          Serial.println("------");
        }
        request->send(200, "text/plain", "message received");//反馈网页
      });
      server.begin();
    }
    
    void loop() {
    
    }

    上传程序,打开串口监视器,我们观察到路由器给 M5 Core2 分配的 IP 地址是 192.168.1.24,记住该地址。

    a320450734f27a3172f6d5cff2e0e078.png

    我们通过浏览器访问 http://192.168.1.24/?name=小明&gender=男, 发现浏览器返回数据如下

    4942b21cd2926bbb2c65fb747aabd9fc.png

    此时串口监视器返回数据如下:

    2e460c85823416a158605892aed6c054.png

    这里我们有两个参数,分别是 name(姓名)与 gender(性别),它们的值分别是“小明”与“男”。在这里你可以添加其他参数,例如加上年龄等参数,浏览器访问链接再次观察串口输出,寻找规律,理解访问参数的意义。

    表单输入

    上面的示例,我们通过参数请求的方式获取了提交的数据,那么我们如何更加简单方便的去提交不同参数呢?在网页中有一个叫表单提交的方法可以让我们去提交这个数据,下面我们来以王大爷的需求为例通过编写 HTML 脚本来进行数据的输入。示例如下:

    #include <WiFi.h>
    #include <FS.h>
    #include <AsyncTCP.h>
    #include <ESPAsyncWebServer.h>
    
    const char* ssid = "xxxxxx";
    const char* password = "xxxxxx";
    
    const char index_home[] PROGMEM = R"rawliteral(
    <html>
     <head>
      <meta charset="utf-8">
      <title>来访登记</title>
      <meta name="Generator" content="vsCode">
      <meta name="Author" content="x">
      <meta name="Keywords" content="">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge chrome=1">
      <meta name="referrer" content="never">
      <meta name="format-detection" content="telephone=no,email=no,address=no">
      <meta name="renderer" content="webkit">
      <meta name="Description" content="">
    
      <style type="text/css">
      *{
        margin: 0;
        padding: 0;
        }
      ul,li{
        list-style:none;
        }
      a{
        text-decoration:none;
        }
      input{
        outline-style:none;
        border: 0px;
      }
      #form1{
        
        margin-top:20px;
        width:80%;
        margin:2px auto;
      }
      #form1 form span{
        color:#999;
      }
      .row { 
        margin-top: 25px;
        height: 50px;
        line-height: 26px;
        border-bottom: 1px solid #c7c6c6;
        width:100%; 
      }
      .input { 
        position: relative;
        width: 100%;
        height: 26px; 
      }
      .input input { 
        display: block;
        width: 100%;
        height: 26px;
        border:none;
        background: none;
        outline:none; 
      }
      .input label { 
        position: absolute;
        top:0;
        left:0;
        height: 26px;
        line-height: 26px;
        font-size: 14px;
        color: #999; 
      }
      .select select{
        display:block;
        width:100%;
        border:none;
        outline:none;
      }
      input[type=date]::-webkit-inner-spin-button { visibility: hidden; }
      .button{
        width:100%;
        height:40px;
        background: #ff961e;
        outline: none;
        margin:20px 0 30px 0;
      }
      .button button{
        border:0px;
        background-color:transparent;
        color:white;
        width: 100%;
        height:40px;
        margin:0 auto;
        font-size:17px;
    }
    
      </style>
     </head>
    
     <body>
        <div id="form1">
            <form action="">
                <br>
                <div class="row ">
                    <div class="input">
                        <span>车牌号码</span>
                        <input type="text" placeholder="例如:苏N·OQN64" name="number_plate" value="">
                    </div>
                </div>
                <div class="row ">
                    <div class="input">
                        <span>访客姓名</span>
                        <input type="text" placeholder="例如:蓟芊" name="name" value="">
                    </div>
                </div>
                <div class="row">
                    <div class="select">
                        <span>性别</span><br>
                        <select name="gender">
                            <option value="男">男</option>
                            <option value="女">女</option>
                        </select><br>
                    </div>
                </div>            
                <div class="row ">
                    <div class="input">
                        <span>体温</span>
                        <input type="text" placeholder="例如:37.5" name="body_temperature" value="">
                    </div>
                </div>            
                <div class="row ">
                    <div class="input">
                        <span>联系电话</span><br>
                        <input type="text" placeholder="例如:18831015911" name="phone_number" value="">
                    </div>
                </div>
                <div class="row">
                    <div class="input">
                        <span>被访人</span><br>
                        <input type="text" placeholder="例如:白允" name="interviewee" value="">
                    </div>
                </div>
                <div class="row">
                    <div class="input">
                        <span>进入时间</span><br>
                        <input type="text" placeholder="例如:2022/4/28 14:56" name="Entry_time" value="">
                    </div>
                </div>           
                <div class="button">
                    <button type="submit">提交信息</button>
                </div>
             </form>
        </div>
     </body>
    </html>)rawliteral";
    
    AsyncWebServer server(80);
    
    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi..");
      }
    
      Serial.println(WiFi.localIP());
      server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
        int paramsNr = request->params();
        Serial.println(paramsNr);
        for (int i = 0; i < paramsNr; i++) {
          AsyncWebParameter* p = request->getParam(i);
          Serial.print("Param name: ");
          Serial.println(p->name());
          Serial.print("Param value: ");
          Serial.println(p->value());
          Serial.println("------");
        }
        request->send(200, "text/html", index_home);
      });
      server.begin();
    }
    
    void loop() {
    
    }

    上传程序,访问 M5core2 对应的 IP 得到如下图所示网页:

    ee0a3908769d770c02f4032499c51a69.png

    打开串口监视器,随机输入一些信息观察串口的数据输出,在这里我们仅需要关注几个地方,网页标题通过 title 标签指定,某一参数输入由 input 标签决定,例如我们要实现年龄输入,只需替换为下列程序:

    <div class="row ">
        <div class="input">
            <span>年龄</span>
            <input type="text" placeholder="例如:18" name="age" value="">
        </div>
    </div>

    这里我们可以通过 w3school在线网页编辑器 实时修改并预览,修改后效果如下:

    ff9cdef343c7ad8f20488247993a753e.png

    对于固定格式的数据,如性别、年级等可参考上面的性别例子在网页编辑器中编辑并预览,相信你一定能轻松搞定。

    数据可视化

    现在我们实现了任意数据表单的输入,那么我们要如何显示数据呢,下面我直接给出网页代码:

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>来访者记录</title>
      <style type="text/css">
        #myInput {
            background-image: url('https://static.runoob.com/images/mix/searchicon.png'); /* 搜索按钮 */
            background-position: 10px 12px; /* 定位搜索按钮 */
            background-repeat: no-repeat; /* 不重复图片 */
            width: 100%;
            font-size: 16px;
            padding: 12px 20px 12px 40px;
            border: 1px solid #ddd;
            margin-bottom: 12px; 
          }
        #output {
            width: 100%;
            height: 100vh;
            margin-top: 20px;
          }
    
          #table {
            border: solid 1px #565656;
            border-collapse: collapse;
            font-family: helvetica,serif;
            font-size: 10pt;
            width: 180mm;
          }
    
          #table th {
            border: solid 1px #565656;
            background-color: #9a7f5b;
            color: #eee;
            text-align: center;
            padding: 5px;
          }
    
          #table td {
            border: solid 1px #565656;
            text-align: center;
            padding: 2px 5px;
          }
      </style>
    </head>
    <body>
    <input type="text" id="myInput" onkeyup="myFunction()" placeholder="搜索...">
        <!-- 设置border="1"以显示表格框线 -->
    <table align="center" id="table" border="1">
      <caption><span style="font-size:20px;">来访者记录</span></caption>
      <thead>
        <tr>
          <th>序号</th>
          <th>车牌号码</th>
          <th>访客姓名</th>
          <th>性别</th>
          <th>体温</th>
          <th>联系电话</th>
          <th>被访人</th>
          <th>进入时间</th>
        </tr>
      </thead>
      <tbody>
         <tr>
         <td>1</td>
         <td>湘P·RBBZG</td>
         <td>邱勤</td>
         <td>男</td>
         <td>36</td>
         <td>1845646545</td>
         <td>小宝</td>
         <td>2022/4/28 14:56</td>
        </td>
        <tr>
         <td>2</td>
         <td>晋B·MIVYF</td>
         <td>简馨</td>
         <td>女</td>
         <td>36</td>
         <td>1845646548</td>
         <td>马克</td>
         <td>12022/4/28 15:56</td>
        </td>
      </tbody>
    </table>
    <div style="text-align:center">
        <a>导出表格</a>                     
     </div>
        <script>
            // 使用outerHTML属性获取整个table元素的HTML代码(包括<table>标签),然后包装成一个完整的HTML文档,设置charset为urf-8以防止中文乱码
            var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementsByTagName("table")[0].outerHTML + "</body></html>";
            // 实例化一个Blob对象,其构造函数的第一个参数是包含文件内容的数组,第二个参数是包含文件类型属性的对象
            var blob = new Blob([html], { type: "application/vnd.ms-excel" });
            var a = document.getElementsByTagName("a")[0];
            // 利用URL.createObjectURL()方法为a元素生成blob URL
            a.href = URL.createObjectURL(blob);
            // 设置文件名
            a.download = "来访者记录表格.xls";
        </script>
            <script>
    function myFunction() {
      // 声明变量
      var input, filter, table, tr, td, i;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("table");
      tr = table.getElementsByTagName("tr");
    
      // 循环表格每一行,查找匹配项
      for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[1];//("td")[1]这里的1指表头的第2列数据,可根据自己需求改为其他列,例如学号或者车牌号等列,该列一般选择为唯一的数据列
        if (td) {
          if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        } 
      }
    }
        </script>
    </body>
    </html>

    将上面的网页代码复制到w3school在线网页编辑器我们得到如下的表格:

    3b99437ec936a4c31cfa0823b6ae66f9.png

    在这个网页中我们点击搜索,填写关键字可以在一定范围内搜索数据,例如我们输入 P 效果如下:

    025cc8224406e40e29db622854aa2fd1.png

    点击导出表格将会下载文件“来访者记录表格.xls”,我们打开该 Excel 文件效果如下:

    2f14760d40bfc4390c50caa2df55ff4c.png

    对比 Excel表格与在线表格,可知两者信息以及格式一致。值得注意的是,即使我们输入错误的信息也会被录入,如上图中的访客 简馨 输入的进入时间有误。在这里篇幅有限我们并没有验证,对于有格式要求的信息如邮箱,电话号码等,有需要的读者可以自行学习前端知识改进上面的网页代码以达到自己的要求。

    对于上面的HTML文件进行分析,我们可以知道关键的几项数据如下:

    <table align="center" id="table" border="1">
      <caption><span style="font-size:20px;">来访者记录</span></caption>
      <thead>
        <tr>
          <th>序号</th>
          <th>车牌号码</th>
          <th>访客姓名</th>
          <th>性别</th>
          <th>体温</th>
          <th>联系电话</th>
          <th>被访人</th>
          <th>进入时间</th>
        </tr>
      </thead>
      <tbody>
         <tr>
         <td>1</td>
         <td>湘P·RBBZG</td>
         <td>邱勤</td>
         <td>男</td>
         <td>36</td>
         <td>1845646545</td>
         <td>小宝</td>
         <td>2022/4/28 14:56</td>
        </td>
        <tr>
         <td>2</td>
         <td>晋B·MIVYF</td>
         <td>简馨</td>
         <td>女</td>
         <td>36</td>
         <td>1845646548</td>
         <td>马克</td>
         <td>12022/4/28 15:56</td>
        </tr>
      </tbody>
    </table>

    将上面的表格的数据替换或者增加数据项,并在网页编辑器中编辑并预览你发现了什么规律,想要实现下图中的表格样式又该如何改呢,这个问题留给大家进行思考。

    6788f93309232113bc8e9b2ae0c7beba.png

    在这个例子中,我们发现,一旦表格的名称与表头信息固定,那么整个表也就随之确定了。其中序号作为必要的数据项放到表格的第一位,为表格排序与统计数据个数,观察 html 表格可知其的最小重复单位如下:

    <tr>
        <td>2</td>//固定序号
        <td>晋B·MIVYF</td>
        <td>简馨</td>
        <td>女</td>
        <td>36</td>
        <td>1845646548</td>
        <td>马克</td>
        <td>12022/4/28 15:56</td>
     </tr>

    按照最小重复单元,我们增加数据项与重复单元,在网页编辑器中进行增删改,实时修改并预览,深刻理解 html 表格。

    表单输入自动添加到表格

    前面我们通过串口监视器观察到了表单数据的提交,那么我们要如何将表单提交的数据添加到表里呢?对于一条数据对应的就是上面的最小重复单元,那么我们可以这样做,对每一条提交的表单数据都将其构造为下面的形式

    <tr>
        <td>data1</td>//固定序号
        <td>data2</td>//第1个提交参数
        <td>data3</td>//第2个提交参数
        ……
        <td>dataN</td>//第N个提交参数
     </tr>

    这里我们不需要考虑每一个数据的数据类型到底是整数,小数还是字符串,我们将其构造后将其视为一个字符串即可。对于多条数据,那么我们如何保存它呢?在 C 语言中我们知道保存一个数据我们可以用变量,保存多个数据我们用数组,那么问题来了我们并不知道我们提交的数据有多少条,数组要求我们使用要先定义数组长度,但这里我们的长度显然是无法预知的。那么有没有可变长度的数组呢,答案是肯定的,我们的解决办法是用链表,至于链表是什么大家可以自己百度了解一下,下面我给出一个链表的简单使用例子。

    #include <QList.h>
    
    QList<String> myList;//声明一个字符串类型的链表
    
    void setup(){
      Serial.begin(115200);
      Serial.println(myList.size());//第一次打印链表长度
      for (int i = 1; i <= 10; i = i++) {//逐次添加随机数到链表
        myList.push_back(String((random(1, 100))));
      }
      Serial.println(myList.size());//添加数据后再次打印链表长度
      for (int i = 1; i <= 10; i++) {//循环打印链表的每一项
        Serial.println(myList.at((i - 1)));
      }
      myList.clear();//清除链表
      Serial.println(myList.size());//再次打印链表长度
    }
    
    void loop(){
    
    }

    上传程序,打开串口监视器结果如下:

    3ea83d2dd44f57eccb37d1c858047a4a.png

    关于链表还有一个注意事项,那就是如果你访问了不存在的数据项,例如我们这里值添加了 10 项数据,但你访问了第 11 项数据,那就会导致程序崩溃,开发板会不断重启,你可以试试这种情况看是否如此,为了避免这种情况的发生我们要适当利用链表长度获取函数来规避这个问题。下面我直接给出表单提交数据放入链表的例子:

    String table = "    <tr>\n";
    for (int i = 1; i <= paramsNr + 1; i++) {
      table = String(table) + String(String("     <td>") + String("data") + String(i) + String("</td>\n"));
    }
    table = String(table) + String("    </tr>\n");
    Serial.println(table);
    table.replace("data1", String(myList.size() + 1));
    for (int i = 0; i < paramsNr; i++) {
      AsyncWebParameter* p = request->getParam(i);
      table.replace(String("data") + String(i + 2), String(p->value()));
    }
    myList.push_back(table);
    Serial.println(myList.at((myList.size() - 1)));

    表格数据替换

    现在我们已经能够获取表单数据并写入链表了,那么我们如何将链表的每一项数据都放入数据查看的 html 网页了呢,我们可以这样做 ,将原表格网页的数据项用一个占位符表示,链表的所有数据项用一个 for 循环全部连接到一起组成一个长字符串,再把这个字符串替换原来的占位符,那么就可以得到完整的 html 表格文件了。实现的方法如下:

    String Tabular_data_variable = "";//声明一个变量用来存放所有链表数据 
    for (int i = 0; i <  myList.size(); i++) {//获取链表长度巧妙利用for循环获取所有数据进行拼接
      Tabular_data_variable = String(Tabular_data_variable) + String(myList.at(i));
      delay(0);//延时函数必须要,否则当链表长度较大时可能会导致看门狗超时重启
    }
    html = index_data;//将数据表格html赋值为原始的数据表格字符串(含占位符)
    html.replace("Tabular_data", Tabular_data_variable);//将占位符Tabular_data替换为有效数据

    提交表单交互

    到这里如果你提交了表单数据,你会发现没有一个交互效果 ,我们并不知道表单数据是否提交成功以及数据提交是否有缺失,当数据不完整时表单数据不应该加入到链表里,只有提交的所有数据参数都不为空字符串时证明数据有效,才能添加到链表,交互的网页代码如下,这是一个提交成功和失败都通用的网页,当然你也可以自己写一个交互网页:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>登记成功</title>
    <script type="text/javascript">
      var num=6;
      function redirect(){
        num--;
        document.getElementById("num").innerHTML=num;
        if(num<0){
          document.getElementById("num").innerHTML=0;
          location.href="/";//回到根目录
          }
        }
      setInterval("redirect()", 1000);
    </script>
    </head>
    
    <body onLoad="redirect();">
    <div class="b">
        <p>
                <h1>信息登记成功!</h1>
                <h1><span id="num"></span>秒后回到主页</h1>
        </p>
      </div>
    </body>
    </html>

    代码效果如下:

    fa6834fe1ba0c75b37358e3917451ed4.png

    域名解析

    我们可以通过串口监视器获取设备的 IP 地址进行访问,但是路由器的分配的 IP 地址是变化的,这点很不方便,当然你也可以登录路由器后台给 M5Core2 分配一个静态 IP。我们这里采取域名解析的方式通过给 M5Core2 分配一个本地域名,这样我们不需要知道IP地址也能方便的 访问设备,实现代码如下:

    #include <ESPmDNS.h>
    
    void setup() {
      Serial.begin(115200);
      if (!MDNS.begin("M5Core2")) {//自定义域名
        Serial.println("Error setting up MDNS responder!");
      }
      MDNS.addService("http", "tcp", 80); //启用DNS服务
    }
    
    void loop() {
    
    }

    通过域名解析,我们只要和设备在同一局域网内,访问 http://m5core2 就能访问相应的服务了。

    读取SD卡文件

    本项目是一个通用型的项目,如果我们将网页文件进行固定那么就丧失了灵活性,因此我们将网络信息以及网页代码等配置文件放入 SD 卡内,从 SD 中去加载所有服务。SD 卡使用的简单示例如下:

    #include "FS.h"
    #include <SD.h>
    #include <SD_MMC.h>
    
    SPIClass sdSPI(VSPI); //定义SD卡软SPI管脚
    #define SD_MISO     38
    #define SD_MOSI     23
    #define SD_SCLK     18
    #define SD_CS       4
    
    String readFile(fs::FS &fs, const char * path) { //读取SD卡指定路径文件
      File file = fs.open(path);
      if (!file) {
        Serial.println("Failed to open file for reading");
      }
      String data = "";
      while (file.available()) {
        data = String(data) + String(char(file.read()));
      }
      file.close();
      return data;
    }
    
    void setup() {
      Serial.begin(115200);
      sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS); //初始化SD卡SPI
      if (!SD.begin(SD_CS, sdSPI)) {
        Serial.println("Card Mount Failed");
        return;
      }
      Serial.println(readFile(SD, "/admin.txt"));
    }
    
    void loop() {
    
    }

    在这里我们可以直接输入 TXT 或者 HTML 文件的路径,便可读取该文件,这里我们读取了 SD 卡根目录下的 admin.txt 文件,该文件作为配置文件用来保存网络信息与一个二维码的数据,该文件内容如下:

    {
      "ssid": "ChinaNet-5678",
      "password": "1234567890",
      "qr": "http://m5core2/"
    }

    M5 超级问卷星网页逻辑

    M5 超级问卷星服务框架如下:

    a791cf4bbf5bc1500dcbf564d0193025.png

    M5 超级问卷星通过区分根目录与 /data 路径来呈现不同的网页内容,其中访问域名或IP进入表单数据提交页,域名或 IP 加 /data 路径进入数据查看与导出页面。

    服务响应逻辑

    M5 超级问卷星服务响应的逻辑如下,访问根目录返回 Home_page.html 页面用于表单提交,当表单提交数据时有两种情况,当提交表单所有数据都不为空返回 success.html 页面,当提交表单某些数据为空时返回 mistake.html,当访问 /data 路径时返回 index_data.html 页面用于查看或导出数据。

    acb888c77333405268b32ee8ddd00837.png

    配置文件结构

    SD 卡配置文件主要由 admin.txt、Home_page.html、success.html、mistake.html、index_data.html 这四个文件构成 ,配置文件详情示意图如下:

    eb57653f429dbc5d5bd0292a09d0a3e8.png

    细节优化

    M5 超级问卷星是一个用于表格数据收集的项目,它集数据库与服务器于一身,不依赖于任何第三方服务,为了交互体验更好,还应当有些许动态提示功能,例如是否有 SD 卡,是否有网络等、我们可以显示一些图像文字和播放音效来进行提示,屏幕上应当显示一个用于外网或者本地的二维码地址,用户直接扫码浏览器打开就可以提交数据,关于这些功能的实现可以参考往期《DIY掌上POS机,或许是最小的收银POS机了!》《超便利!教你用ESP32 开发板 DIY 掌上服务器》这两篇教程,其中有功能实现详细的描述,这里就不再赘述,可通过链接进行查看。

    程序下载

    以上就是M5 超级问卷星的项目介绍,如果你不想下载IDE只想体验该项目,那么你可以访问 https://docs.m5stack.com/zh_CN/download 根据你自己的系统下载M5Burner烧录工具进行安装,打开软件按照下面的步骤进行烧录体验,其中SD卡网页模板与配置文件请通过本教程附件进行下载,直接解压到的SD卡修改网络信息即可体验。

    a00f902059185d57c4a0aedbd526ebad.png

    使用说明

    1. 烧录固件;

    2. 将附件提供的模板解压到 SD 卡;

    3. 打开 admin.txt 文件修改网络信息(不需要外网访问二维码地址可以不改,如果有使用内网穿透请填写外网地址);

    4. SD 卡放入 M5core2 并重启设备;

    5. 等待 M5core2 初始化并进入二维码显示页面(若初始化错误请按照屏幕显示与语音提示使用正确配置文件或更换 SD 卡);

    6. 访问 http://m5core2/ 按演示视频提交表单数据(体验提交成功与失败两种情况);

    7. 访问 http://m5core2/data 查看数据并导出 Excel 查看;

    8. 尝试修改模板文件自定义表单文件与数据表格重复上述步骤理解本项目。

    总结

    根据上面的理论基础我们便能完成 M5 超级问卷星的项目制作了,其中具体实现细节由于篇幅限制,这里就不再讨论,大家可以通过附件下载程序源代码进行查看,其中必要的程序说明已经注释,对此项目有任何建议或者疑问均可评论区留言。使用 M5 超级问卷星你能够轻松利用表单收集任意文本信息并且导出为 Excel 表格,如果你会网页前端知识你还可以定制属于自己的网页样式满足个性化,与问卷星不同这个是你个人私有的服务器且可以灵活定制各种功能(数据分类汇总,表格可视化等),如果你想要定制或者有其他项目需求请联系我,如果你有好玩的创意也可以评论区留言,或许下期你的创意就会得到实现,我也会@你来见证你的好创意。

    我是默,我们下期见。

    代码下载

    关注本公众号“铁熊玩创客”,回复“M5问卷星”获取完整代码。

    43cf922d82ad9c261b6b1d2a6b25e65f.png

    欢迎转发朋友圈。如需转载,请注明出处和原作者。

    b3d8e22c199f4ed0df372bfa57d33a6c.png

    点个在看支持一下吧 ↓↓↓

    展开全文
  • 而且部分实施的项目也有很多失败,除了常见的业务需求定义不清、项目执行不力之外,很重要的原因是因为其数据模型设计,企业级数据仓库,Inmon推荐采用3范式进行数据建模,但是不排除其他的方法,但是Inmon的...

    🍅 作者主页:不吃西红柿 

    🍅 简介:CSDN博客专家🏆、信息技术智库公号作者✌  华为云享专家、HDZ核心组成员。 简历模板、PPT模板、学习资料、面试题库、技术互助点击下方「信息技术智库」跳转文末都给你!

    目录

    🍅 信息技术智库 🍅


    文章很长,前言一定要看

    拥有本篇文章,意味着你拥有一本完善的书籍,本篇文章整理了数据仓库领域,几乎所有的知识点,文章内容主要来源于以下几个方面:

    1. 源于「数据仓库交流群」资深数据仓库工程师的交流讨论,如《sql行转列的千种写法》。
    2. 源于群友面试大厂遇到的面试真题,整理投稿给我,形成《面试题库》。
    3. 源于笔者在系统学习过程中整理的笔记和一点理解
    4. 源于技术网站的优质文章和高赞答案

    本篇文章尤其适合初级程序员准备面试,以及作为工作中的指导手册,对资深程序员来说也可夯实基础。

    当然,技术学习仅仅依靠一篇文章还是不够的,可加入公众号和技术交流群(联系方式见文末),群里有很多数据仓库领域资深大佬,大家经常在群里讨论技术热点问题、互相解决工作难题、安排内推、甚至有部门leader直接发出岗位邀请。「西红柿🍅」也会持续更新优质文章,也欢迎热爱学习总结的小伙伴有偿投稿,共同推动中国信息技术行业发展,让我们一起加油吧!

    目录

    一、数据仓库的8个发展阶段

        1.概念阶段(1978-1988)

        2.萌芽阶段

        3.集成阶段

        4.确立阶段(1991)

        5.数据集市(1994-1996)

        6.争吵与混乱(1996-1997)

        7.合并(1998-2001)

        8.未来

    二、四种常见数据模型

        1.为什么要进行数据仓库建模

        2.四种常见模型

            2.1 维度模型

                2.1.1 星型模型

                2.1.2 雪花模型

                2.1.3 星座模型

            2.2 范式模型

            2.3 Data Vault模型

            2.4 Anchor模型

        3.数据模型的评价标准

    三、三种事实表(设计原则,设计方法)

        1.三种事实表概述

        2.三种事实表对比

        3.事实表设计 8 大原则

        4.事实表设计方法

            第一步:选择业务过程及确定事实表类型

            第二步:声明粒度

            第三步:确定维度

            第四步:确定事实

    四、多维体系结构

        1.总线架构

        2.一致性维度

        3.一致性事实

        4.小编有话

    五、数据仓库规范设计

        1.为什么要进行规范设计

        2.设计规范 - 指标

        3.命名规范 - 表命名

            3.1 常规表

            3.2 中间表

            3.3 临时表

            3.4 维度表

        4.开发规范

        5.流程规范

    六、元数据管理

        1.业务元数据

        2.技术元数据

        3.管理元数据

        4.小编有话

    七、维度表

        1.什么是维度表

        2.维度表设计原则

        3.维度表设计方法

    八、三范式与反范式

        1.第一范式

        2.第二范式

        3.第三范式

        4.反范式化

        5.范式化设计和反范式化设计的优缺点

            5.1 范式化 (时间换空间)

            5.2 反范式化(空间换时间)

        6.OLAP和OLTP中如何设计范式

    九、数据仓库架构-Lambda和Kappa   

        1.Lambda架构原理

        2.Lambda架构的缺点

        3.Kappa架构原理

        4.Lambda架构和Kappa架构优缺点对比

        5.数据架构评价标准

        6.小编有话

    十、数据治理(目的、方法、流程)

        1.什么是数据治理

        2.数据治理的目的

        3.数据治理的方法

        4.数据质量8个衡量标准

        5.数据治理流程

    十一、ETL

        1.什么是ETL

        2.ETL & ELT

        3.常用的ETL工具

            3.1 sqoop

            3.2 DataX

            3.3 Kettle

            3.4 canal

    十二、数据应用-OLAP

        1.OLAP和OLTP的区别

        2.OLAP分类

        3.OLAP基本操作

        4.OLAP选型

    十三、数据倾斜

        1.数据倾斜表现

            1.1 hadoop中的数据倾斜表现

            1.2 hive中数据倾斜

            1.3 Spark中的数据倾斜

        2.数据倾斜产生原因

        3.解决数据倾斜思路

            2.1 业务逻辑

            2.2 程序层面

            2.3 调参方面

            2.4 从业务和数据上解决


     

    一、数据仓库的8个发展阶段

    1、概念阶段(1978-1988)

    数据仓库最早的概念可以追溯到20世纪70年代MIT的一项研究,该研究致力于开发一种优化的技术架构并提出这些架构的指导性意见。

    第一次,MIT的研究员将业务系统和分析系统分开,将业务处理和分析处理分成不同的层次,并采用单独的数据存储和完全不同的设计准则。同时,MIT的研究成果与80年代提出的信息中心(InformationCenter)相吻合:即把那些新出现的、不可以预测的、但是大量存在的分析型的负载从业务处理系统中剥离出来。

    但是限于当时的信息处理和数据存储能力,该研究只是确立了一个论点:这两种信息处理的方式差别如此之大,以至于它们只能采用完全不同的架构和设计方法。

    2、萌芽阶段

    80年代中后期,作为当时技术最先进的公司,DEC已经开始采用分布式网络架构来支持其业务应用,并且DEC公司首先将业务系统移植到其自身的RDBMS产品:RdB。并且,DEC公司从工程部、销售部、财务部以及信息技术部抽调了不同的人员组建了新的小组,不仅研究新的分析系统架构,并要求将其应用到其全球的财务系统中。该小组结合MIT的研究结论,建立了TA2TechnicalArchitecture2)规范,该规范定义了分析系统的四个组成部分:

    • 数据获取
    • 数据访问
    • 目录
    • 用户服务

    其中的数据获取和数据访问目前大家都很清楚,而目录服务是用于帮助用户在网络中找到他们想要的信息,类似于业务元数据管理;用户服务用以支持对数据的直接交互,包含了其他服务的所有人机交互界面,这是系统架构的一个非常大的转变,第一次将交互界面作为单独的组件提出来。

    3、集成阶段

    全企业集成(EnterpriseIntergration1988)同时,IBM也在处理信息管理不同方面的问题,其最烦人的问题是不断增加的信息孤岛,IBM的很多客户要面对很多分立系统的数据集成问题,而这些系统有不同的编码方式和数据格式。

    1988年,为解决全企业集成问题,IBM爱尔兰公司的BarryDevlinPaulMurphy第一次提出了信息仓库(InformationWarehouse的概念,将其定义为:一个结构化的环境,能支持最终用户管理其全部的业务,并支持信息技术部门保证数据质量,并在1991年在DECTA2的基础上把信息仓库的概念包含进去,并称之为VITAL规范,将PC、图形化界面、面向对象的组件以及局域网都包含在VITAL里,并定义了85种信息仓库的组件,包括数据抽取、转换、有效性验证、加载、Cube开发和图形化查询工具等。但是IBM只是将这种领先的概念用于市场宣传,而没有付诸实际的架构设计。这是IBM有一个领域上创新后停止不前导致丧失其领先地位。因此,在90年代初期,数据仓库的基本原理、框架架构,以及分析系统的主要原则都已经确定,主要的技术,包括关系型数据存取、网络、C/S架构和图形化界面均已具备,只欠东风了。

    同时,1988年-1991年,一些前沿的公司已经开始建立数据仓库

    4、确立阶段(1991)

    企业级数据仓库(EDW19911991年,BillInmon出版了其有关数据仓库的第一本书,这本书不仅仅说明为什么要建数据仓库、数据仓库能给你带来什么,更重要的是,Inmon第一次提供了如何建设数据仓库的指导性意见,该书定义了数据仓库非常具体的原则,包括:数据仓库是面向主题的(Subject-Oriented)、集成的(Integrated)、包含历史的(Time-variant)、相对稳定的(Nonvolatile)、面向决策支持的(DecisionSupport)面向全企业的(EnterpriseScope)最明细的数据存(AtomicDetail)数据快照式的数据获取(SnapShotCapture)这些原则到现在仍然是指导数据仓库建设的最基本原则,虽然中间的一些原则引发一些争论,并导致一些分歧和数据仓库变体的产生。

    BillInmon凭借其这本书奠定了其在数据仓库建设的位置,被称之为数据仓库之父

    5、数据集市(1994-1996)

    数据仓库发展的第一明显分歧是数据集市概念的产生。由于企业级数据仓库的设计、实施很困难,使得最早吃数据仓库螃蟹的公司遭到大面积的失败,因此数据仓库的建设者和分析师开始考虑只建设企业级数据仓库的一部分,然后再逐步添加,但是这有背于BillInmon的原则:各个实施部分的数据抽取、清洗、转换和加载是独立,导致了数据的混乱与不一致性。而且部分实施的项目也有很多失败,除了常见的业务需求定义不清、项目执行不力之外,很重要的原因是因为其数据模型设计,在企业级数据仓库中,Inmon推荐采用3范式进行数据建模,但是不排除其他的方法,但是Inmon的追随者固守OLTP系统的3范式设计,从而无法支持DSS系统的性能和数据易访问性的要求。

    这时,Ralph Kimball出现了,他的第一本书“TheDataWarehouseToolkit”掀起了数据集市的狂潮,这本书提供了如何为分析进行数据模型优化详细指导意见,从DimensionalModeling大行其道,也为传统的关系型数据模型和多维OLAP之间建立了很好的桥梁。从此,数据集市在很多地方冒了出来,并获得很大成功,而企业级数据仓库已逐渐被人所淡忘。

    6、争吵与混乱(1996-1997)

    企业级数据仓库还是部门级数据集市?关系型还是多维?BillInmonRalphKimball一开始就争论不休,其各自的追随者也唇舌相向,形成相对立的两派:Inmon派和Kimball派(有点象少林和武当,呵呵)

    在初期,数据集市的快速实施和较高的成功率让Kimball派占了上风,但是很快,他们也发现自己陷入了某种困境:企业中存在67个不同的数据集市,分别有不同的ETL,相互之间的数据也不完全一致。同时,各个项目实施中也任意侵犯了Inmon开始定下的准则:把数据集市当成众多OLTP系统之后的有一个系统,而不是一个基础性的集成性的东西,为保证数据的准确性和实时性,有的甚至可以由OLTP系统直接修改数据集市里面的数据,为了保证系统的性能,有的数据集市删除了历史数据。等等,不一而足。

    当然,这导致了一些新的应用的出现,例如ODS,但是人们对DataWarehouseDataMartODS的概念非常的模糊,经常混为一谈。有人说OLAP就是数据仓库,也有人说我要ODSDataMart,不要Datawarehouse,也有人说,我DataMart建多了,自然就有DataWarehouse了。但是BillInmon一直很旗帜鲜明:你可以打到几万吨的小鱼小虾,但是这些小鱼小虾加起来不是大鲸鱼

    7、合并(1998-2001)

    经过多翻争吵,证明one-size-fits-all是不可能的,你需要不同的BI架构来满足不同的业务需求。BillInmon也推出了新的BI架构CIFCorporationinformationfactory),把Kimball的数据集市也包容进来了,第一次,Kimball承认了Inmon,但是仍然还有很多人在争论是自顶向下,还是自底向上。

    8、未来

    未来几个方向:时效性方向的实时数仓;数据质量方向的数据治理;数据中台、数据湖(欢迎留言讨论!

    推荐阅读:

    数据库、数据仓库、数据平台、数据中台、数据湖到底是什么?


     

    二、四种常见数据模型

    大数据时代,维度建模已成为各大厂的主流方式。

    维度建模从分析决策的需求出发构建模型,为分析需求服务。重点关注用户如何快速的完成数据分析,可以直观的反应业务模型中的业务问题,需要大量的数据预处理、数据冗余,有较好的大规模复杂查询的响应性能

    1、为什么要进行数据仓库建模

    • 性能:良好的模型能帮我们快速查询需要的数据,减少数据的IO吞吐
    • 成本:减少数据冗余、计算结果复用、从而降低存储和计算成本
    • 效率:改善用户使用数据的体验,提高使用数据的效率
    • 改善统计口径的不一致性,减少数据计算错误的可能性

    2、四种常见模型

    2.1 维度模型

    维度建模按数据组织类型划分可分为星型模型、雪花模型、星座模型。Kimball老爷爷维度建模四部曲:

    选择业务处理过程 > 定义粒度 > 选择维度 > 确定事实

    2.1.1 星型模型

    星型模型主要是维表和事实表,以事实表为中心,所有维度直接关联在事实表上,呈星型分布。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQKswjhsQiafst5d5g50jc93wtRqzzCYicW2d13ys71Xl66acXr2yeZ44g/640?wx_fmt=png

    2.1.2 雪花模型

    雪花模型,在星型模型的基础上,维度表上又关联了其他维度表。这种模型维护成本高,性能方面也较差,所以一般不建议使用。尤其是基于hadoop体系构建数仓,减少join就是减少shuffle,性能差距会很大。

    星型模型可以理解为,一个事实表关联多个维度表,雪花模型可以理解为一个事实表关联多个维度表,维度表再关联维度表。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQf8B5cIiboDpeaIKHBW7wlgnQ82v3g9A6of7CWRaEbsVVmvsib6iasmdlQ/640?wx_fmt=png

    2.1.3 星座模型

    星座模型,是对星型模型的扩展延伸,多张事实表共享维度表。

    星座模型是很多数据仓库的常态,因为很多数据仓库都是多个事实表的。所以星座模型只反映是否有多个事实表,他们之间是否共享一些维度表。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQshEECGzZAgj2bRO4oYMkqbIeiazj65ccU0yJKw81J3SndpvR06iaBLSw/640?wx_fmt=png

    2.2 范式模型

    即实体关系(ER)模型,数据仓库之父Immon提出的,从全企业的高度设计一个3NF模型,用实体加关系描述的数据模型描述企业业务架构,在范式理论上符合3NF。此建模方法,对建模人员的能力要求非常高。

    特点:设计思路自上而下,适合上游基础数据存储,同一份数据只存储一份,没有数据冗余,方便解耦,易维护,缺点是开发周期一般比较长,维护成本高。

    详见后文:三范式与反范式

    2.3 Data Vault模型

    DataVault由Hub(关键核心业务实体)、Link(关系)、Satellite(实体属性) 三部分组成 ,是Dan Linstedt发起创建的一种模型方法论,它是在ER关系模型上的衍生,同时设计的出发点也是为了实现数据的整合,并非为数据决策分析直接使用。

    2.4 Anchor模型

    高度可扩展的模型,所有的扩展只是添加而不是修改,因此它将模型规范到6NF,基本变成了K-V结构模型。企业很少使用。

    信息技术智库关注领取技术资料、面试真题、简历模板和PPT模板;一起交流工作难题、面试套路、职场经验、内推直通车公众号

    3、数据模型的评价标准

    数据模型建设的怎么样,极度依赖规范设计,如果代码风格是“千人千面”,那么恐怕半年下来,业务系统就没法看了。没有什么比“数据系统”更看重“法制”了,规范体系不仅能保障数据建设的一致性,也能够应对业务交接的情况,更能够为自动化奠定基础。

    1. 业务过程清晰:ODS就是原始信息,不修改;DWD面向基础业务过程;DIM描述维度信息;DWS针对最小场景做指标计算;ADS也要分层,面向跨域的建设,和面向应用的建设;
    2. 指标可理解:按照一定业务事务过程进行业务划分,明细层粒度明确、历史数据可获取,汇总层维度和指标同名同义,能客观反映业务不同角度下的量化程度;
    3. 核心模型相对稳定:如果业务过程运行的比较久,过程相对固定,就要尽快下沉到公共层,形成可复用的核心模型;
    4. 高内聚低耦合:各主题内数据模型要业务高内聚,避免在一个模型耦合其他业务的指标,造成该模型主题不清晰和性价比低。

    小编有话

    • 在传统企业数仓中,业务相对稳定,以范式建模为主。如电信、金融行业等
    • 在互联网公司,业务变化快,需求来来回回的改,计算和存储也不是问题,我们更关心快速便捷的满足业务需求,所以以维度建模为主。


     

    三、三种事实表

    事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设 计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度 和与业务过程有关的度量。

    1、三种事实表概述

    事实表有三种类型 : 事务事实表、周期快照事实表累积快照事实表

    • 1.1 事务事实表

    也称原子事实表,描述业务过程,跟踪控件或时间上某点的度量事件,保存的是最原子的数据;

    个人理解:类似于mysql binlog日志,每一次相关的 change 都记录下来,生成一行新的数据

    • 1.2 周期快照事实表

    以一个周期为时间间隔,来记录事实,一般周期可以是每天、每周、每月、每年等;

    个人理解:只看某个业务过程,比如订单收货,数据按订单收货时间来切分,周期可以为每天、每月等。

    • 1.3 累积快照事实

    用来描述过程开始和结束之间的关键步骤事件,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点;当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改;

    个人理解:要看整个生命周期的多个业务过程,比如:创建订单 → 买家付款 → 卖家发货 → 买家确认收货。粒度是一个订单一行数据,创建订单时间,付款时间,发货时间,收货时间,分别作为一个字段,便于计算不同业务过程的时间间隔。

    2、三种事实表对比

    事务事实表 

    周期快照事实表 

    累积快照事实表 

    时期/时间 

    离散事务时间点 

    以有规律的、可预测的 

    用于时间跨度不确定的不断变化的工作流 

    日期维度 

    事务日期 

    快照日期 

    相关业务过程涉及的多个日期 

    粒度

    每行代表实体的一个事务 

    每行代表某时间周期的一个实体 

    每行代表一个实体的生命周期 

    事实 

    事务事实

    累积事实

    相关业务过程事实和时间间隔事实 

    事实表加载 

    插入 

    插入 

    插入与更新 

    事实表更新 

    不更新 

    不更新 

    业务过程变更时更新 

    3、事实表设计 8 大原则

    • 原则 1:尽可能包含所有与业务过程相关的事实
      • 分析哪些事实与业务过程相关,是设计过程中非常重要的关注点;
      • 在事实表中,尽量包含所有与业务过程相关的事实,即使存在冗余,由于事实通常是数字型,存储开销不会太大;

    • 原则 2:只选择与业务过程相关的事实
      • 如,订单的下单这个业务过程,事实表中不应该存在支付金额这个表示支付业务过程的事实;

    • 原则 3:分解不可加性事实为可加的组件
      • 如,订单的优惠率,应分解为订单原价金额与订单优惠金额两个事实存储在事实表中;

    • 原则 4:在选择维度和事实之前必须先声明粒度
      • 因为原子粒度提供了最大限度的灵活性,可以支持无法预期的各种细节层次的用户需求;
      • 粒度用于确定事实表中一行所表示业务的细节层次,决定了维度模型的扩展性;
      • 每个维度和事实必须与所定义的粒度保持一致;
      • 设计事实表时,粒度定义越细越好,一般从最低级别的原子粒度开始;

    • 原则 5:在同一个事实表中不能有多种不同粒度的事实
      • 粒度为票一级;(实际业务中,一个订单可以同时支付多张票)
      • 票支付金额和票折扣金额,两个事实的粒度为 “票级”,与定义的粒度一致;
      • 订单支付金额和订单票数,两个事实的粒度为 “订单级”,属于上一层订单级数据,与 “票级” 事实表的粒度不一致,且不能进行汇总;
      • 如果,以订单金额和订单票数这两个维度汇总总金额和总票数,会造成大量的重复计算;
      • 疑问:怎么判断不同事实的粒度是否相同?

    • 原则 6:事实的单位要保持一致
      • 如,订单金额、订单优惠金额、订单运费这 3 个事实,应该采用统一的计量单位,统一为元或者分,以方便使用;

    • 原则 7:对事实的 null 值要处理
      • 原因:在数据库中,null 值对常用数字型字段的 SQL 过滤条件都不生效;如,大于、小于、等于、大于或等于、小于或等于;
      • 处理:用 0 代替 null ;

    • 原则 8:使用退化维度提高事实表的易用性
      • 易用性:对事实表,更较少关联操作、过滤查询、控制聚合层次、排序数据、定义主从关系等;
      1. 事实表中存储各种类型的常用维度信息,较少下游用户使用时关联多个表的操作;
      2. 通过退化维度,可以实现对事实表的过滤查询、控制聚合层次、排序数据、定义主从关系等;
    • 在 Kimball 的维度建模中,通常按照星形模型的方式设计,通过事实表的外键关联专门的维表,这种方式来获取维度,谨慎使用退化维表;这与大数据领域的事实表设计不一样;
      • 思路:通过增加冗余存储,减少计算开销,提高使用效率;

    4、事实表设计方法

    Kimball 的维度模型设计 4 步法:选择业务过程、声明粒度、确定维度、确定事实;

    当前的互联网大数据环境,维度模型的设计,是基于 Kimball 的四步维度建模方法进行了更进一步的改进:

    • 第一步:选择业务过程及确定事实表类型
      • 淘宝的一个交易订单,选择 “买家付款” 这个业务过程,则事实表类型应为只包含买家付款这一个业务过程的 “单事务事实表”;
      • 如选择了所有 4 个业务过程,并且需要分享各业务过程的时间间隔,则事实表类型应为包含了所有 4 个业务过程的 “累积快照事实表”;
      • 如是选择 “买家付款” 这个业务过程,还是选择 “创建订单” 和 “买家付款” 这两个业务过程,具体根据业务情况来定;
      • 思路:详细分析需求,对业务的整个生命周期进行分析,明确关键的业务步骤,从而选择与需求有关的业务过程;
      • 以实例说明:如何选择业务过程?如何确定事实表类型?
      1. 分析业务的生命周期,业务过程通常使用行为动词表示业务执行的活动
      2. 明确关键的业务步骤:该订单流转的业务过程有 4 个:创建订单 买家付款 卖家发货 买家确认收货;
      3. 根据业务需求,选择与维度建模有关的业务过程;
      4. 根据所选的业务过程确定事实表类型;

    • 第二步:声明粒度
      • 粒度的作用:
      • 粒度的选择:尽量选择最细级别的原子粒度,以确保事实表的应用具有最大的灵活性;
      1. 灵活性:支持无法预期的各种细节层次的用户需求;
      2. 对于订单级别,粒度可以定义为最细的订单级别;(如,父子订单,事实表的粒度可以定 “子订单级别” ;)
      3. 粒度的声明,意味着精确定义事实表的每一行所表示的业务含义
      4. 明确的粒度能够确保对实表中行的意思的理解不会产生混淆,保证所有的事实按照同样的细节层次记录;

    • 第三步:确定维度
      • 如,淘宝订单 “付款事务事实表” 中,粒度为 “子订单”,相关的维度有买家、卖家、商品、收货人信息、业务类型、订单时间等;
      • 完成了粒度声明,就意味着确定了主键,对应的维度组合以及相关的维度字段也可以确定了;
      • 选择维度的原则:应该选择能够描述清楚业务过程所处的环境的维度信息;

    • 第四步:确定事实
      • 确定原则:选择与业务过程有关的所有事实,且事实的粒度要与所声明的事实表的粒度一致
      • 思路:可以通过回答 “过程的度量是什么” 来确定;
      • 注意:将不可加性事实分解为可加的组件;(分解的原则:可以通过分解后的可加的属性值,计算得到不可加性事实)

    四、多维体系结构

    在Kimball的维度建模的数据仓库中,关于多维体系结构(MD)有三个关键性概念:总线架构(Bus Architecture),一致性维度(Conformed Dimension)和一致性事实(Conformed Fact)。 

    1、总线架构

    多维体系结构(总线架构) 数据仓库领域里,有一种构建数据仓库的架构,叫Multidimensional Architecture(MD),中文一般翻译为“多维体系结构”,也称为“总线架构”(Bus Architecture)。

    多维体系结构的创始人是数据仓库领域中最有实践经验的Kimball博士。多维体系结构主要包括后台(Back Room)和前台(Front Room)两部分。后台也称为数据准备区(Staging Area),是MD架构的最为核心的部件。在后台,是一致性维度的产生、保存和分发的场所。同时,代理键也在后台产生。前台是MD架构对外的接口,包括两种主要的数据集市,一种是原子数据集市,另一种是聚集数据集市。

    原子数据集市保存着最低粒度的细节数据,数据以星型结构来进行数据存储。聚集数据集市的粒度通常比原子数据集市要高,和原子数据集市一样,聚集数据集市也是以星型结构来进行数据存储前台还包括像查询管理、活动监控等为了提供数据仓库的性能和质量的服务。在多维体系结构中,所有的这些基于星型机构来建立的数据集市可以在物理上存在于一个数据库实例中,也可以分散在不同的机器上,而所有这些数据集市的集合组成的分布式的数据仓库。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQQk9flT8rs9Jhb2XAVBbHZPWMDsGYzA4swIJjlF2a4rqfGxMiciaM1xQw/640?wx_fmt=png

    2、一致性维度 

    在多维体系结构中,没有物理上的数据仓库,由物理上的数据集市组合成逻辑上的数据仓库。而且数据集市的建立是可以逐步完成的,最终组合在一起,成为一个数据仓库。如果分步建立数据集市的过程出现了问题,数据集市就会变成孤立的集市,不能组合成数据仓库,而一致性维度的提出正式为了解决这个问题。

    一致性维度的范围是总线架构中的维度,即可能会在多个数据集市中都存在的维度,这个范围的选取需要架构师来决定。一致性维度的内容和普通维度并没有本质上区别,都是经过数据清洗和整合后的结果。 一致性维度建立的地点是多维体系结构的后台(Back Room),即数据准备区。

    在多维体系结构的数据仓库项目组内需要有专门的维度设计师,他的职责就是建立维度和维护维度的一致性。在后台建立好的维度同步复制到各个数据集市。这样所有数据集市的这部分维度都是完全相同的。建立新的数据集市时,需要在后台进行一致性维度处理,根据情况来决定是否新增和修改一致性维度,然后同步复制到各个数据集市。这是不同数据集市维度保持一致的要点。

    在同一个集市内,一致性维度的意思是两个维度如果有关系,要么就是完全一样的,要么就是一个维度在数学意义上是另一个维度的子集。

    例如,如果建立月维度话,月维度的各种描述必须与日期维度中的完全一致,最常用的做法就是在日期维度上建立视图生成月维度。这样月维度就可以是日期维度的子集,在后续钻取等操作时可以保持一致。如果维度表中的数据量较大,出于效率的考虑,应该建立物化视图或者实际的物理表。这样,维度保持一致后,事实就可以保存在各个数据集市中。虽然在物理上是独立的,但在逻辑上由一致性维度使所有的数据集市是联系在一起,随时可以进行交叉探察等操作,也就组成了数据仓库。

    3、一致性事实

    在建立多个数据集市时,完成一致性维度的工作就已经完成了一致性的80%-90%的工作量。余下的工作就是建立一致性事实。一致性事实和一致性维度有些不同,一致性维度是由专人维护在后台(Back Room),发生修改时同步复制到每个数据集市,而事实表一般不会在多个数据集市间复制。需要查询多个数据集市中的事实时,一般通过交叉探查(drill across)来实现。

    为了能在多个数据集市间进行交叉探查,一致性事实主要需要保证两点:第一个是KPI的定义及计算方法要一致,第二个是事实的单位要一致性。如果业务要求或事实上就不能保持一致的话,建议不同单位的事实分开建立字段保存。


     

          这样,一致性维度将多个数据集市结合在一起,一致性事实保证不同数据集市间的事实数据可以交叉探查,一个分布式的数据仓库就建成了。

    小遍有话

    • 总线矩阵:业务过程和维度的交点;
    • 一致性维度:同一集市的维度表,内容相同或包含;
    • 一致性事实:不同集市的同一事实,需保证口径一致,单位统一。

    追求一致性必然会增加开发工作量,但长期来说,使用方便、运维简单;一致性和性能之间,需要平衡。
     

    五、数据仓库规范设计

    1、为什么要进行规范设计

    无规矩、不方圆。规范设计是在具体开发工作之前制定的,过程中不断进行完善。目的在于约束 N 个人对齐认知,按照一个标准或流程进行开发,以保证数据一致性,流程清晰且稳定。

    一个良好的规范设计,应当起到以下作用:提高开发效率,提升质量,降低沟通对齐成本,降低运维成本等。

    下面西红柿🍅将带领大家盘一盘数据仓库有哪些规范,从中挑选几个重点细说:

    • 设计规范

                逻辑架构、技术架构、分层设计、主题划分、方法论

    •  命名规范

                各层级命名、任务命名、表命名、字段命名、指标命名等 

    • 模型规范

                建模方法、建模工具、血缘关系、维度退化、一致性维度、元数据管理

    • 开发规范

                脚本注释、字段别名、编码规范、脚本格式、数据类型、缩写规范 

    • 流程规范

                需求流程、工程流程、上线流程、调度流、调度和表生命周期管理

    2、设计规范 - 指标

    • Step1:面向主题域管理

    为了提高指标管理的效率,你需要按照业务线、主题域和业务过程三级目录方式管理指标。
     

    • Step2:划分原子指标和派生指标

    原子指标 + 原子指标  = 派生指标
     

    • Step3:进行指标命名规范

    需要遵循两个原则:易懂与统一

    1. 易懂,就是看到指标的名称,就可以基本判断这个指标归属于哪个业务过程;
    2. 统一,就是要确保派生指标和它继承的原子指标命名是一致的。

    对于原子指标,标名称适合用“动作 + 度量”的命名方式(比如注册用户数、购买用户数)

    对于派生指标,应该严格遵循“时间周期 + 统计粒度 + 修饰词 + 原子指标”的命名方式。(比如30天内黑卡会员购买用户数)

    • Step4:分级管理

    指标确实是多,如果一视同仁去管理其实很难,所以可以按照下面的原则进行等级划分

    1. 一级指标:数据中台直接产出,核心指标(提供给公司高层看的)、原子指标以及跨部门的派生指标。
    2. 二级指标:基于中台提供的原子指标,业务部门创建的派生指标。

    3、命名规范 - 表命名

    3.1 常规表

    常规表是我们需要固化的表,是正式使用的表,是目前一段时间内需要去维护去完善的表。

    规范:分层前缀[dwd|dws|ads|bi]_业务域_主题域_XXX_更新频率|全量/增量。 

    业务域、主题域我们都可以用词根的方式枚举清楚,不断完善,粒度也是同样的,主要的是时间粒度、日、月、年、周等,使用词根定义好简称。

    建议格式: dwd_xxx_xxx_da

    • di :每日增量
    • da:每日全量
    • mi:每月增量
    • ma:每月全量

    3.2 中间表

    中间表一般出现在Job中,是Job中临时存储的中间数据的表,中间表的作用域只限于当前Job执行过程中,Job一旦执行完成,该中间表的使命就完成了,是可以删除的(按照自己公司的场景自由选择,以前公司会保留几天的中间表数据,用来排查问题)。

    建议格式:mid_table_name_[0~9]

    table_name是我们任务中目标表的名字,通常来说一个任务只有一个目标表。这里加上表名,是为了防止自由发挥的时候表名冲突,而末尾大家可以选择自由发挥,起一些有意义的名字,或者简单粗暴,使用数字代替,各有优劣吧,谨慎选择。

    3.3 临时表

    临时表是临时测试的表,是临时使用一次的表,就是暂时保存下数据看看,后续一般不再使用的表,是可以随时删除的表。

    建议格式:tmp_xxx

    只要加上tmp开头即可,其他名字随意,注意tmp开头的表不要用来实际使用,只是测试验证而已。

    3.4 维度表

    维度表是基于底层数据,抽象出来的描述类的表。维度表可以自动从底层表抽象出来,也可以手工来维护。

    建议格式:dim_xxx

    维度表,统一以dim开头,后面加上,对该指标的描述,可以自由发挥。

    4、开发规范

    1

    表和列的注释释是否有缺失,复杂计算逻辑是否有注释释

    2

    任务是否支持多次重跑而输出不变,不能有insert into语句

    3

    分区表是否使用分区键过滤并且有有效裁剪

    4

    外连接的过逑条件是否使用正确,例如在左连接的where语句存在右表的过滤条件

    5

    关联小表,是否使用/*+ map join * / hint

    6

    不允许引用别的计算任务临时表

    7

    原则上不允许存在一个任务更新多个目标表

    8

    是否存在笞、迪卡尔积

    9

    禁止在代码里面使用drop 111ble、creat它111ble、renaiue 111ble、chan零column等ddl语句

    10

    使用动态分区时,有没有检查分区键值为NULL的情况

    11

    DQC质量监控规则是否配置,严禁棵奔

    12

    代码中有没有进行适当的规避数据倾斜语句

    13

    Where条件中is null语句有没有进行空字符串处理

    5、流程规范

    根据阿里流程规范,本文将数据仓库研发流程抽象为如下几点:

    1. 需求阶段:数据产品经理应如何应对不断变化的业务需求。
    2. 设计阶段:数据产品经理、数据开发者应如何综合性能、成本、效率、质量等因素,更好地组织与存储数据。
    3. 开发阶段:数据研发者如何高效、规范地进行编码工作。
    4. 测试阶段:测试人员应如何准确地暴露代码问题与项目风险,提升产出质量。
    5. 发布阶段:如何将具备发布条件的程序平稳地发布到线上稳定产出。
    6. 运维阶段:运维人员应如何保障数据产出的时效性和稳定性。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQ8x2HXSKH6OjYUG1XFtbeYz1DMRuMkSDDf3hZnHibqMiaOlickib5xPgLOQ/640?wx_fmt=png

    六、元数据管理

    1、业务元数据

    1. 描述 ”数据背后的业务含义
    2. 主题定义:每段 ETL、表背后的归属业务主题。
    3. 业务描述:每段代码实现的具体业务逻辑。
    4. 标准指标:类似于 BI 中的语义层、数仓中的一致性事实;将分析中的指标进行规范化。
    5. 标准维度:同标准指标,对分析的各维度定义实现规范化、标准化。
    6. 不断的进行维护且与业务方进行沟通确认。

    2、技术元数据

    • 数据源元数据
      • 例如:数据源的 IP、端口、数据库类型;数据获取的方式;数据存储的结构;原数据各列的定义及 key 指对应的值。

    • ETL 元数据
      • 根据 ETL 目的的不同,可以分为两类:数据清洗元数据数据处理元数据
      • 数据清洗,主要目的是为了解决掉脏数据及规范数据格式;因此此处元数据主要为:各表各列的"正确"数据规则;默认数据类型的"正确"规则。
      • 数据处理,例如常见的表输入表输出;非结构化数据结构化;特殊字段的拆分等。源数据到数仓、数据集市层的各类规则。比如内容、清理、数据刷新规则。

    • 数据仓库元数据
      • 数据仓库结构的描述,包括仓库模式、视图、维、层次结构及数据集市的位置和内容;业务系统、数据仓库和数据集市的体系结构和模式等。

    • BI 元数据
      • 汇总用的算法、包括各类度量和维度定义算法。数据粒度、主题领域、聚集、汇总、预定义的查询与报告。

    3、管理元数据

    管理领域相关,包括管理流程、人员组织、角色职责等。

    4、小编有话

    在日常工作中,元数据的管理主要体现在元数据的采集、存储、查询、应用几个方面。原则上应从规范化,到脚本化,到工具化的方向进行建设。

    • 采集:元数据采集时尽可能详细,真实,可通过工具生成或者勾选,避免手动录入带来不规范等问题
    • 存储:存储元数据要做到不失真,元数据变更时及时同步
    • 查询:通过网页或库表等方式,方便快捷的看到元数据,辅助进行开发
    • 应用:数据血缘、优化调度依赖、数据治理等


     

    七、维度表

    1、什么是维度表

    ​维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实” , 将环境描述为“维度”。

    维度表包含了事实表中指定属性的相关详细信息,最常用的维度表有日期维度、城市维度等。

    日期维表:

    num

    字段名

    字段中文名

    描述

    数据类型

    1

    date

    日期

    日期 yyyMMdd格式

    bigint

    2

    week

    星期,数字型

    星期,数字型 0-6

    bigint

    3

    week_cn

    星期中文名

    星期中文名 星期一……

    string

    4

    year_weeks

    一年中的第几周

    一年中的第几周 1 2 3……

    bigint

    5

    mon_dt

    本周周一日期

    本周周一日期

    bigint

    6

    sun_dt

    本周周日日期

    本周周日日期

    bigint

    7

    month

    年月

    年月,yyyyMM格式

    bigint

    8

    month_short

    月份简写

    月份简写,MM格式1~12

    bigint

    9

    month_cn

    月份中文名

    月份中文名 一月……

    string

    10

    quarter

    季度

    季度,yyyyQ1\2\3\4

    string

    11

    quarter_short

    季度 数字型

    季度 数字型 1-4

    bigint

    12

    quarter_cn

    季度中文名

    季度中文名 第一季度……

    string

    13

    year

    年份

    年份,yyyy格式

    bigint

    2、维度表设计原则

    维度的作用一般是查询约束、分类汇总以及排序等,我们在进行维度表设计时,应当提前考虑:


     

    1)维度属性尽量丰富,为数据使用打下基础

    比如淘宝商品维度有近百个维度属性,为下游的数据统计、分析、探查提供了良好的基础。

    2)给出详实的、富有意义的文字描述

    属性不应该是编码,而应该是真正的文字。在间里巴巴维度建模中, 一般是编码和文字同时存在,比如商品维度中的商品 ID 和商品标题、 类目 ID 和 类目名称等。ID 一 般用于不同表之间的关联,而名称一般用 于报表标签

    3)区分数值型属性和事实

    数值型宇段是作为事实还是维度属性,可以参考字段的一般用途。如果通常用于查询约束条件或分组统计,则是作为维度属性;如果通常 用于参与度量的计算, 则是作为事实。比如商品价格,可以用于查询约 束条件或统计价格区间 的商品数量,此时是作为维度属性使用的;也可 以用于统计某类目 下商品的平均价格,此时是作为事实使用的。另外, 如果数值型字段是离散值,则作为维度属性存在的可能性较大;如果数 值型宇段是连续值 ,则作为度量存在的可能性较大,但并不绝对,需要 同时参考宇段的具体用途。

    4)沉淀出通用的维度属性,为建立一致性维度做好铺垫

    有些维度属性获取需要进行比较复杂的逻辑处理,有些需要通过多表关联得到,或者通过单表 的不同宇段混合处理得到,或者通过对单表 的某个字段进行解析得到。此时,需要将尽可能多的通用的维度属性进 行沉淀。一方 面,可以提高下游使用的方便性,减少复杂度;另一方面,可以避免下游使用解析时由于各自逻辑不同而导致口径不 一致。

    5)退化维度(Degenerate Dimension

    在维度类型中,有一种重要的维度称作为退化维度。这种维度指的是直接把一些简单的维度放在事实表中。退化维度是维度建模领域中的一个非常重要的概念,它对理解维度建模有着非常重要的作用,退化维度一般在分析中可以用来做分组使用。

    6)缓慢变化维(Slowly Changing Dimensions

    维度的属性并不是始终不变的,它会随着时间的流逝发生缓慢的变化,这种随时间发生变化的维度我们一般称之为缓慢变化维(SCD),缓慢变化维一般使用代理健作为维度表的主健。


     

    推荐阅读缓慢变化维度的10种处理方式
     

    缓慢变化维的三种常用处理方式:

     TYPE1 直接覆盖原值

    适用于:不看历史数据,简单粗暴

    https://mmbiz.qpic.cn/mmbiz_jpg/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQ1qA7qcY7ia3c1htggyt8sPkC9fjv3u3eptX0ibkwviaic9YoYHR3BHLkkg/640?wx_fmt=jpeg

     TYPE2 拉链表

    需要在维度行再增加三列:有效日期、截止日期、行标识(可选)。

    在旧的一行数据增加关链时间(end_date),新的一行数据增加开链时间关链时间,多条数据加起来是一个完整的时间周期。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQjLpBffAmpWfWbuFKvKuibU9JCpoicSapJ4CYx12AB4ODR31ctynAoyjw/640?wx_fmt=png

     TYPE3 增加属性列

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQbFA9wmtmkE35LwT6dJX1COG9EvuuSfgHbGm4wson8u2r7x4AYdr2jg/640?wx_fmt=png

    3、维度表设计方法

    • 第一步:选择维度或新建维度。作为维度建模的核心,在企业级数 据仓库中必须保证维度的唯一性。以淘宝商品维度为例,有且只允许有 一个维度定义。

    • 第二步:确定主维表。此处的主维表一般是 ODS 表,直接与业务 系统同步。以淘宝商品维度为例, s_auction_auctions 是与前台商品中心 系统同步的商品表,此表即是主维表。

    • 第三步:确定相关维表。数据仓库是业务源系统的数据整合,不同业务系统或者同 一业务系统中的表之间存在 关联性。根据对业务的梳 理,确定哪些表和主维表存在关联关系,并选择其中的某些表用于生成维度属性。

    • 第四步 :确定维度属性 。本步骤主要 包括两个阶段,其中第 一 个阶 段是从主维表 中选择维度属性或生成新的维度属性;第 二个阶段是从相 关维表中选择维度属性或生成新 的维度属性。以淘宝商品维度为例,从 主维表 (s_auction_auctions)和类目、 SPU、卖家、店铺等相关维表中 选择维度属性或生成新 的维度属性。


     

    八、三范式与反范式

    范式是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。

           关系数据库中的关系必须满足一定的要求,即满足不同的范式。大数据生态中,各类强大的查询引擎层出不穷,相对廉价的磁盘和分布式技术,也让数据冗余变得可接受甚至更加方便。

           在创建一个数据库的过程中,范化是将其转化为一些表的过程,这种方法可以使从数据库得到的结果更加明确。这样可能使数据库产生重复数据,从而导致创建多余的表。范化是在识别数据库中的数据元素、关系以及定义所需的表和各表中的项目等这些初始工作之后的一个细化的过程。

    1、第一范式

    1NF要求属性具有原子性,即列不可再分解;

    表:字段1、 字段2(字段2.1、字段2.2)、字段3 ......

    如学生(学号,姓名,性别,出生年月日)

    有些钢筋可能要问西红柿了,姓名可以拆成姓、名两列, “出生年月日” 也可以拆成年、月、日三个字段。所以就不满足第一范式了!!!这里再强调一下原子性,原子性是根据使用方便来自定义的最小单位。中国人一般姓名一起用,美国就习惯姓名分别存两字段。

    2、第二范式

    2NF要求记录有惟一标识,即不存在部分依赖;

    简单来说就是拆表,以人为粒度做一张明细表,以课程号为粒度做一张维度表,两表关联使用,消除了数据冗余

    表:学号、课程号、姓名、学分;

    这个表明显说明了两个事务:学生信息, 课程信息;由于非主键字段必须依赖主键,这里学分依赖课程号姓名依赖与学号,所以不符合二范式。

    可能会存在问题:

    • 数据冗余:每条记录都含有相同信息;
    • 删除异常:删除所有学生成绩,就把课程信息全删除了;
    • 插入异常:学生未选课,无法记录进数据库;
    • 更新异常:调整课程学分,所有行都调整。

    正确做法: 
    学生:Student(学号, 姓名); 
    课程:Course(课程号, 学分); 
    选课关系:StudentCourse(学号, 课程号, 成绩)。

    3、第三范式

    3NF是对字段的冗余性,要求任何字段不能由其他字段派生出来,它要求字段没有冗余,即不存在传递依赖;

    表: 学号, 姓名, 年龄, 学院名称, 学院电话

    因为存在依赖传递: (学号) → (学生)→(所在学院) → (学院电话) 。

    可能会存在问题:

    • 数据冗余:有重复值;
    • 更新异常:有重复的冗余信息,修改时需要同时修改多条记录,否则会出现数据不一致的情况 。

    正确做法:

    学生:(学号, 姓名, 年龄, 所在学院);

    学院:(学院, 电话)。

    4、反范式化

    一般说来,数据库只需满足第三范式(3NF)就行了。

        没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余,达到以空间换时间的目的

      〖例〗:有一张存放商品的基本表,如表1所示。“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。

        在Rose 2002中,规定列有两种类型:数据列计算列。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。

    5、范式化设计和反范式化设计的优缺点

    5.1 范式化 (时间换空间)

    优点:

    • 范式化的表减少了数据冗余,数据表更新操作快、占用存储空间少。

    缺点:

    • 查询时需要对多个表进行关联,查询性能降低。 
    • 更难进行索引优化

    5.2 反范式化(空间换时间)

    反范式的过程就是通过冗余数据来提高查询性能,但冗余数据会牺牲数据一致性

    优点:

    • 可以减少表关联
    • 可以更好进行索引优化

    缺点:

    • 存在大量冗余数据
    • 数据维护成本更高(删除异常,插入异常,更新异常)

    6、OLAP和OLTP中范式设计

    OLAP 一般冗余比较多,以查询分析为主,这种一般都是采用反范式设计,以提高查询效率。更新一般是定时大批量数据插入。
     

    OLTP 则是尽可能消除冗余,以提高变更的效率。因为这种应用无时无刻不在频繁变化。

     

    九、数据仓库架构-Lambda和Kappa

    随着数据量的暴增数据实时性要求越来越高,以及大数据技术的发展驱动企业不断升级迭代,数据仓库架构方面也在不断演进,分别经历了以下过程:早期经典数仓架构 > 离线大数据架构 > Lambda > Kappa > 混合架构。

    架构

    组成

    特点

    经典数仓架构

    关系型数据库(mysql、oracle)为主

    数据量小,实时性要求低

    离线大数据架构

    hive,spark为主

    数据量大,实时性要求低

    Lambda

    hive,spark负责存量,strom/Flink负责实时计算

    数据量大,实时性要求高

    Kappa

    kafka、strom、Flink

    多业务,多数据源,事件型数据源

    混合架构

    ps.西红柿的举例若有不当,欢迎指正

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQ4X2cMia5VZPHdFc2rEBWrmz4xS7IJkqt1tKyArdeba8kuS1f9TJulbA/640?wx_fmt=png

    1、Lambda架构原理

    Lambda架构的核心思想是把大数据系统拆分成三层:Batch LayerSpeed LayerServing Layer。其中,Batch Layer负责数据集存储以及全量数据集的预查询。


     

    Speed Layer主要负责对增量数据进行计算,生成Realtime ViewsServing Layer用于响应用户的查询请求,它将Batch ViewsRealtime Views的结果进行合并,得到最后的结果,返回给用户,如下图:
     

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQZoAOTNNyDb86HhouCRWBr8ypDIe0lYb1L62WdvpibnceYqoxSoM7qIQ/640?wx_fmt=png

    2、Lambda架构的缺点

    Lambda架构解决了大数据量下实时计算的问题,但架构本身也存在一定缺点。

    • 实时与批量计算结果不一致引起的数据口径问题:因为批量和实时计算走的是两个计算框架和计算程序,算出的结果往往不同,经常看到一个数字当天看是一个数据,第二天看昨天的数据反而发生了变化。
    • 批量计算在计算窗口内无法完成:在IOT时代,数据量级越来越大,经常发现夜间只有4、5个小时的时间窗口,已经无法完成白天20多个小时累计的数据,保证早上上班前准时出数据已成为每个大数据团队头疼的问题。
    • 开发和维护的复杂性问题:Lambda 架构需要在两个不同的 API(application programming interface,应用程序编程接口)中对同样的业务逻辑进行两次编程:一次为批量计算的ETL系统,一次为流式计算的Streaming系统。针对同一个业务问题产生了两个代码库,各有不同的漏洞。这种系统实际上非常难维护
    • 服务器存储大:数据仓库的典型设计,会产生大量的中间结果表,造成数据急速膨胀,加大服务器存储压力。

    3、Kappa架构原理

    Kappa架构的核心思想包括以下三点:

    • 用Kafka或者类似的分布式队列系统保存数据,你需要几天的数据量就保存几天。
    • 当需要全量重新计算时,重新起一个流计算实例,从头开始读取数据进行处理,并输出到一个新的结果存储中。
    • 当新的实例做完后,停止老的流计算实例,并把老的一些结果删除。

    • https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQO33xBudXgbEVlhjv1nEu5SNtYy0plCDcwa3CGK63a01U7Wv1Mm0qXA/640?wx_fmt=png

    • 在Kappa架构下,只有在有必要的时候才会对历史数据进行重复计算,并且实时计算和批处理过程使用的是同一份代码。

    4、Lambda架构和Kappa架构优缺点对比

    项目

    Lambda

    Kappa

    数据处理能力

    可以处理超大规模的历史数据

    历史数据处理的能力有限

    机器开销

    批处理和实时计算需一直运行,机器开销大

    必要时进行全量计算,机器开销相对较小

    存储开销

    只需要保存一份查询结果,存储开销较小

    需要存储新老实例结果,存储开销相对较大

    开发、测试难度

    实现两套代码,开发、测试难度较大

    只需面对一个框架,开发、测试难度相对较小

    运维成本

    维护两套系统,运维成本大

    只需维护一个框架,运维成本小

    5、数据架构评价标准

    • 响应速度:数据架构的主要场景包括:业务开发、数据产品、运营分析三大类,不论是那种场景,数据架构均应该在尽可能短的时间内响应需求;

    • 可复用性:只有复用能力上来了,响应速度才能提上来,体现在下游依赖、调用次数、核心字段覆盖率等指标上;
    • 稳定性:除了日常任务不出问题以外,一旦发现了问题,能在多短的时间内定位和恢复问题,就非常重要;
    • 健壮性:除了电商等已经耕耘多年的领域外,绝大多数业务模型,都会快速的变化,如何适应这种变化,就非常考验架构功底。

    6、小编有话

    • Lambda 将全量历史数据和实时增量数据合并输出。
    • Kappa 两个流协作输出,queries每次使用最新一个流处理结果

    目前很多准实时增量批处理方案也能满足实时性需求,从稳定性和运维成本上也表现更佳。

    比如kudu(存储)+impala(计算)准实时方案,可以实现千万级数据的增量更新和olap查询,性能优异。
     

    十、数据治理(目的、方法、流程)

    1、什么是数据治理

    数据治理(Data Governance)是组织中涉及数据使用的一整套管理行为。由企业数据治理部门发起并推行,关于如何制定和实施针对整个企业内部数据的商业应用和技术管理的一系列政策和流程。

    数据的质量直接影响着数据的价值,并且直接影响着数据分析的结果以及我们以此做出的决策的质量。

    我们常说,用数据说话,用数据支撑决策管理,但低质量的数据、甚至存在错误的数据,必然会"说假话"!!!数据治理即提高数据的质量,发挥数据资产价值

    2、数据治理的目的

    • 降低风险
    • 建立数据使用内部规则
    • 实施合规要求
    • 改善内部和外部沟通
    • 增加数据价值
    • 方便数据管理
    • 降低成本
    • 通过风险管理和优化来帮助确保公司的持续生存

    3、数据治理的方法

    从技术实施角度看,数据治理包含”“”“”“”“这五个步骤,即业务和数据资源梳理、数据采集清洗、数据库设计和存储、数据管理、数据使用。 

    数据资源梳理:数据治理的第一个步骤是从业务的视角厘清组织的数据资源环境和数据资源清单,包含组织机构、业务事项、信息系统,以及以数据库、网页、文件和 API 接口形式存在的数据项资源,本步骤的输出物为分门别类的数据资源清单。

    数据采集清洗:通过可视化的 ETL 工具(例如阿里的 DataX,Pentaho Data Integration)将数据从来源端经过抽取 (extract)、转换 (transform)、加载 (load) 至目的端的过程,目的是将散落和零乱的数据集中存储起来。

    基础库主题库建设:一般情况下,可以将数据分为基础数据、业务主题数据和分析数据。基础数据一般指的是核心实体数据,或称主数据,例如智慧城市中的人口、法人、地理信息、信用、电子证照等数据。主题数据一般指的是某个业务主题数据,例如市场监督管理局的食品监管、质量监督检查、企业综合监管等数据。而分析数据指的是基于业务主题数据综合分析而得的分析结果数据,例如市场监督管理局的企业综合评价、产业区域分布、高危企业分布等。那么基础库和主题库的建设就是在对业务理解的基础上,基于易存储、易管理、易使用的原则抽像数据存储结构,说白了,就是基于一定的原则设计数据库表结构,然后再根据数据资源清单设计数据采集清洗流程,将整洁干净的数据存储到数据库或数据仓库中。

    元数据管理:元数据管理是对基础库和主题库中的数据项属性的管理,同时,将数据项的业务含义与数据项进行了关联,便于业务人员也能够理解数据库中的数据字段含义,并且,元数据是后面提到的自动化数据共享、数据交换和商业智能(BI)的基础。需要注意的是,元数据管理一般是对基础库和主题库中(即核心数据资产)的数据项属性的管理,而数据资源清单是对各类数据来源的数据项的管理。

    血缘追踪:数据被业务场景使用时,发现数据错误,数据治理团队需要快速定位数据来源,修复数据错误。那么数据治理团队需要知道业务团队的数据来自于哪个核心库,核心库的数据又来自于哪个数据源头。我们的实践是在元数据和数据资源清单之间建立关联关系,且业务团队使用的数据项由元数据组合配置而来,这样,就建立了数据使用场景与数据源头之间的血缘关系。数据资源目录:数据资源目录一般应用于数据共享的场景,例如政府部门之间的数据共享,数据资源目录是基于业务场景和行业规范而创建,同时依托于元数据和基础库主题而实现自动化的数据申请和使用。

    质量管理:数据价值的成功发掘必须依托于高质量的数据,唯有准确、完整、一致的数据才有使用价值。因此,需要从多维度来分析数据的质量,例如:偏移量、非空检查、值域检查、规范性检查、重复性检查、关联关系检查、离群值检查、波动检查等等。需要注意的是,优秀的数据质量模型的设计必须依赖于对业务的深刻理解,在技术上也推荐使用大数据相关技术来保障检测性能和降低对业务系统的性能影响,例如 Hadoop,MapReduce,HBase 等。

    商业智能(BI:数据治理的目的是使用,对于一个大型的数据仓库来说,数据使用的场景和需求是多变的,那么可以使用 BI 类的产品快速获取需要的数据,并分析形成报表,比较知名的产品有 Microsoft Power BI,QlikView,Tableau,帆软等。

    数据共享交换:数据共享包括组织内部和组织之间的数据共享,共享方式也分为库表、文件和 API 接口三种共享方式,库表共享比较直接粗暴,文件共享方式通过 ETL 工具做一个反向的数据交换也就可以实现。我们比较推荐的是 API 接口共享方式,在这种方式下,能够让中心数据仓库保留数据所有权,把数据使用权通过 API 接口的形式进行了转移。API 接口共享可以使用 API 网关实现,常见的功能是自动化的接口生成、申请审核、限流、限并发、多用户隔离、调用统计、调用审计、黑白名单、调用监控、质量监控等等。

    4、数据质量8个衡量标准

    • 数据的准确性

    数据采集值或者观测值和真实值之间的接近程度,也叫做误差值,误差越大,准确度越低。

    • 数据的精确性

    指对同一对象的观测数据在重复测量时所得到不同数据间的接近程度。

    • 数据的真实性
    • 数据的及时性

    数据能否在需要的时候得到保证,比如月初的财务对账,能不能在月初就完成

    • 数据的即时性

    指数据采集时间节点和数据传输的时间节点,一个数据在数据源头采集后立即存储,并立即加工呈现,就是即时数据,而经过一段时间之后再传输到信息系统中,则数据即时性就稍差。

    • 数据的完整性

    应采集和实际采集到数据之间的比例。

    • 数据的全面性

    完整性衡量的是应采集和实际采集的差异。而全面性指的是数据采集点的遗漏情况。

    • 数据的关联性

    指各个数据集之间的关联关系。比如员工工资数据和员工绩效考核数据是通过员工这个资源关联在一起来的。

    信息技术智库关注领取技术资料、面试真题、简历模板和PPT模板;一起交流工作难题、面试套路、职场经验、内推直通车公众号

    5、数据治理流程

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icT2evG4mmN199tTlibT6WE0kVhEic4GWibqkIyxGpic0uCibZeqo393RvPWlXhQOMEqUcAg0quj01joQfA/640?wx_fmt=png

    基本流程发现数据质量问题 > 定义数据质量规则 > 质量控制 > 质量评估 > 质量优化
     

    十一、ETL

    1、什么是ETL

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

           抽取(Extract主要是针对各个业务系统及不同服务器的分散数据,充分理解数据定义后,规划需要的数据源及数据定义,制定可操作的数据源,制定增量抽取和缓慢渐变的规则。

           转换(transform主要是针对数据仓库建立的模型,通过一系列的转换来实现将数据从业务模型到分析模型,通过ETL工具可视化拖拽操作可以直接使用标准的内置代码片段功能、自定义脚本、函数、存储过程以及其他的扩展方式,实现了各种复杂的转换,并且支持自动分析日志,清楚的监控数据转换的状态并优化分析模型。

    装载(Load主要是将经过转换的数据装载到数据仓库里面,可以通过直连数据库的方式来进行数据装载,可以充分体现高效性。在应用的时候可以随时调整数据抽取工作的运行方式,可以灵活的集成到其他管理系统中。

    2、ETL & ELT

    伴随着数据仓库的发展(传送门:数据仓库的八个发展阶段),数据量从小到大,数据实时性从T+1到准实时、实时,ETL也在不断演进。

     

    • 在传统数仓中,数据量小,计算逻辑相对简单,我们可以直接用ETL工具实现数据转换(T),转换之后再加载到目标库,即(Extract-Transform-Load)。

    • 但在大数据场景下,数据量越大越大,计算逻辑愈发复杂,数据清洗需放在运算能力更强的分布式计算引擎中完成,ETL也就变成了ELT(Extract-Load-Transform)。

    即:Extract-Transform-Load  >>  Extract-Load-Transform

    通常我们所说的ETL,已经泛指数据同步、数据清洗全过程,而不仅限于数据的抽取-转换-加载。

    3、常用的ETL工具

    下面小编将介绍几类ETL工具(sqoopDataXKettlecanalStreamSets)。

    3.1 sqoop

    • 是Apache开源的一款在Hadoop和关系数据库服务器之间传输数据的工具。
    • 可以将一个关系型数据库(MySQL ,Oracle等)中的数据导入到Hadoop的HDFS中,也可以将HDFS的数据导出到关系型数据库中。
    • sqoop命令的本质是转化为MapReduce程序。
    • sqoop分为导入(import)和导出(export),
    • 策略分为table和query
    • 模式分为增量和全量。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQnA0yZMLxKRa7gXcbjXWfzoEMQMncdZZ7nT2d4ibgwcjsjJAIiavdcs3g/640?wx_fmt=png

    https://mmbiz.qpic.cn/mmbiz_jpg/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQjhaq786n4DAqRnpDLcFVLicUXGNIs2KtNUKOIj5rHQk5UhD4VtMZfFA/640?wx_fmt=jpeg

    3.2 DataX

    • DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台
    • 实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQ2z5OF8icXcIibzBicDPlzFMBu6n7HmTGibu6c2TgiboXMB3TXWSmPGPGasw/640?wx_fmt=png

    https://mmbiz.qpic.cn/mmbiz_jpg/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQQmwyS3CbSrARotMwgQBwHViauduaLyskicMC9xFm3XhLjQI3whNqqS8A/640?wx_fmt=jpeg

    3.3 Kettle

    • 一款国外免费开源的、可视化的、功能强大的ETL工具,纯java编写,可以在Windows、Linux、Unix上运行,数据抽取高效稳定。

    3.4 canal

    • canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据实时订阅和消费,目前主要支持了MySQL,也支持mariaDB。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQOEfD9nvZNfh23YscISVg2WfmZ7gNibIyAaugosmicT0zCfqS9slGkg6Q/640?wx_fmt=png

    3.5 StreamSets

    • 是大数据实时采集ETL工具,可以实现不写一行代码完成数据的采集和流转。通过拖拽式的可视化界面,实现数据管道(Pipelines)的设计和定时任务调度。
    • 创建一个Pipelines管道需要配置数据源(Origins)、操作(Processors)、目的地(Destinations)三部分。

    4、ETL加载策略

    4.1 增量

    • 有些表巨大,我们需要选择增量策略,新增delta数据需要和存量数据merge合并。

    只有新增(full join。能拿更新表就拿更新表)

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQicaxNmdEbWvh9aZpRgFiaicIp0jZ3Ot9dRHibIkfWHtkSUlTYXKcCn0lgA/640?wx_fmt=png

    • 新增+删除
      • history-table Left join delet-table where delect-table.value is null == 表a
      • 表a full join update-table (能拿update就拿update)

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQPD50eHPmrbjkt54ibibuOIYzgF6m4AkKFfBRys1XV9K7ZEU6MQZEfcjQ/640?wx_fmt=png

    4.2 全量

    每天一个全量表,也可一个hive天分区一个全量。

    4.3 流式

    使用kafka,消费mysql binlog日志到目标库,源表和目标库是1:1的镜像。

    5、小编有话

    无论是全量还是增量的方式,都会浪费多余的存储或通过计算去重,得到最新的全量数据。为解决这一问题,西红柿墙裂建议kafka的数据同步方案,源表变化一条,目标表消费一条,目标表数据始终是一份最新全量数据,且为实时同步的。 


     

    ps.极端情况下可能会丢数,需要写几个监控脚本(详见上文数据质量部分)和补数脚本即可~

     

    十二、数据应用-OLAP

    1、olap和oltp的区别

    OLTP

    OLAP

    对象

    业务开发人员

    分析决策人员

    功能

    日常事务处理

    面向分析决策

    模型

    关系模型

    多维模型

    数据量

    几条或几十条记录

    >百万于万条记录

    操作类型

    增、删、查、改(CRUD)

    查询为主

    总体概括

    联机事务处理

    在线分析处理

    2、OLAP分类

    • MOLAP基于多维数组的存储模型,也是OLAP最初的形态,特点是对数据进行预计算,以空间换效率,明细和聚合数据都保存在cube。但生成cube需要大量时间和空间。

    • ROLAP基于关系模型进行存储数据,不需要预计算,按需即时查询。明细和汇总数据都保存在关系型数据库事实表中。其特点是与事务实体对应,关系清晰;但一般需要较为复杂的数据准备。在响应前端需求时,一般较快,但取决于计算引擎能力。

    • HOLAP,混合模型,细节数据以ROLAP存放,聚合数据以MOLAP存放。这种方式相对灵活,且更加高效。可按企业业务场景和数据粒度进行取舍,没有最好,只有最适合。

    https://mmbiz.qpic.cn/mmbiz_jpg/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQePa7Lmibficd4hujUunO2E3aftVa5dFc2aKzR2f13NM3vfNfRyIOuIicA/640?wx_fmt=jpeg

    3、OLAP基本操作

    • 钻取:维的层次变化,从粗粒度到细粒度,汇总数据下钻到明细数据。如通过季度销售数据钻取每个月的销售数据。

    • 上卷:钻取的逆,向上钻取。从细粒度到粗粒度,细粒度数据到不同维层级的汇总。eg. 通过每个月的销售数据汇总季度、年销售数据。
    • 切片特定维数据(剩余维两个)。eg. 只选电子产品销售数据。

    • 切块维区间数据(剩余维三个)。eg. 第一季度到第二季度销售数据。

    • 旋转维位置互换(数据行列互换),通过旋转可以得到不同视角的数据。

    https://mmbiz.qpic.cn/mmbiz_png/Jy3qP5tic4icSUZPphtibOGia8NhkDFBViaPQNheDVKGZExDtl0sibo0N5HC6hCVzXBW0XVB3wHXCL4ssHCA6w53DkOA/640?wx_fmt=png

    4、OLAP选型

    4.1 druid

    • 实时查询和分析的高容错、高性能开源分布式系统,用于解决如何在大规模数据集下进行快速的、交互式的查询和分析。
    • 实时的数据消费,真正做到数据摄入实时、查询结果实时。
    • 扩展性强,支持 PB 级数据
    • 极高的高可用保障,支持滚动升级。
    • druid属于时间存储,删除操作比较繁琐,且不支持查询条件删除数据,只能根据时间范围删除数据。Druid能接受的数据的格式相对简单,比如不能处理嵌套结构的数据。

    4.2 kylin

    • 可扩展超快olap引擎,Hadoop/Spark上百亿数据规模
    • 提供 Hadoop ANSI SQL 接口
    • 交互式查询能力,用户可以与Hadoop数据进行亚秒级交互
    • 百亿以上数据集构建多维立方体(MOLAP CUBE)
    • 与BI工具无缝整合,如Tableau,PowerBI/Excel,MSTR,QlikSense,Hue和SuperSet


     

    十三、数据倾斜

    1、数据倾斜表现

    1.1 hadoop中的数据倾斜表现

    • 有一个多几个Reduce卡住,卡在99.99%,一直不能结束。
    • 各种container报错OOM
    • 异常的Reducer读写的数据量极大,至少远远超过其它正常的Reducer
    • 伴随着数据倾斜,会出现任务被kill等各种诡异的表现。


     

    1.2 hive中数据倾斜

    一般都发生在Sql中group by和join on上,而且和数据逻辑绑定比较深。
     

    1.3 Spark中的数据倾斜

    Spark中的数据倾斜,包括Spark Streaming和Spark Sql,表现主要有下面几种:

    • Executor lost,OOM,Shuffle过程出错;
    • Driver OOM;
    • 单个Executor执行时间特别久,整体任务卡在某个阶段不能结束;
    • 正常运行的任务突然失败;

    2、数据倾斜产生原因

    我们以Spark和Hive的使用场景为例。

    在做数据运算的时候会涉及到,count distinct、group by、join on等操作,这些都会触发Shuffle动作。一旦触发Shuffle,所有相同key的值就会被拉到一个或几个Reducer节点上,容易发生单点计算问题,导致数据倾斜。
     

    一般来说,数据倾斜原因有以下几方面:

    1)key分布不均匀;

    2)建表时考虑不周

    举一个例子,就说数据默认值的设计吧,假设我们有两张表:

        user(用户信息表):userid,register_ip

        ip(IP表):ip,register_user_cnt

    这可能是两个不同的人开发的数据表。如果我们的数据规范不太完善的话,会出现一种情况:

    user表中的register_ip字段,如果获取不到这个信息,我们默认为null;

    但是在ip表中,我们在统计这个值的时候,为了方便,我们把获取不到ip的用户,统一认为他们的ip为0。
     

    两边其实都没有错的,但是一旦我们做关联了,这个任务会在做关联的阶段,也就是sql的on的阶段卡死。
     

    3)业务数据激增

    比如订单场景,我们在某一天在北京和上海两个城市多了强力的推广,结果可能是这两个城市的订单量增长了10000%,其余城市的数据量不变。
     

    然后我们要统计不同城市的订单情况,这样,一做group操作,可能直接就数据倾斜了。
     

    3、解决数据倾斜思路

    很多数据倾斜的问题,都可以用和平台无关的方式解决,比如更好的数据预处理异常值的过滤等。因此,解决数据倾斜的重点在于对数据设计和业务的理解,这两个搞清楚了,数据倾斜就解决了大部分了。

    1)业务逻辑

    我们从业务逻辑的层面上来优化数据倾斜,比如上面的两个城市做推广活动导致那两个城市数据量激增的例子,我们可以单独对这两个城市来做count,单独做时可用两次MR,第一次打散计算,第二次再最终聚合计算。完成后和其它城市做整合。

    2)程序层面

    比如说在Hive中,经常遇到count(distinct)操作,这样会导致最终只有一个Reduce任务。

    我们可以先group by,再在外面包一层count,就可以了。比如计算按用户名去重后的总用户量:
     

    (1)优化前 

    只有一个reduce,先去重再count负担比较大:

    select name,count(distinct name)from user;

    (2)优化后

    // 设置该任务的每个job的reducer个数为3个。Hive默认-1,自动推断。

    set mapred.reduce.tasks=3;

    // 启动两个job,一个负责子查询(可以有多个reduce),另一个负责count(1):

    select count(1) from (select name from user group by name) tmp;
     

    3)调参方面

    Hadoop和Spark都自带了很多的参数和机制来调节数据倾斜,合理利用它们就能解决大部分问题。
     

    4)从业务和数据上解决数据倾斜

    很多数据倾斜都是在数据的使用上造成的。我们举几个场景,并分别给出它们的解决方案。
     

    一个原则:尽早过滤每个阶段的数据量。

    1. 数据有损的方法:找到异常数据,比如ip为0的数据,过滤掉。
    2. 数据无损的方法:对分布不均匀的数据,单独计算。
    3. hash:先对key做一层hash,先将数据随机打散让它的并行度变大,再汇聚。
    4. 数据预处理:就是先做一层数据质量处理,类似于数据仓库维度建模时,底层先处理数据质量。

    记得点赞、收藏哦

    🍅 信息技术智库 🍅

    🍅 行业资料:关注领取PPT模板、简历模板、行业经典书籍PDF。
    🍅 交流加群:大佬指点迷津,你的问题往往有人遇到过,求资源在群里喊一声。
    🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
    🍅 学习资料:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、前端等。

    ↘ ↘ ↘ ↘ ↘

    展开全文
  • 首先,要想成为一名优秀的前端工程师,对于web的各种标签其命名时,同时给出id和name属性的值是应该的.下面是各种html初学者的标签使用清单:web当中同时使用id,name的属性是一个好的习惯.各个表单元素都写...
  • 数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf数据仓库解决方案v1.0.pdf
  • 数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx数据仓库解决方案v1.0.docx
  • 拥有本篇文章,意味着你拥有一本完善的书籍,本篇文章整理了数据仓库领域,几乎所有的知识点。
  • 数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据仓库解决方案v1.0 (2).pdf数据...
  • 数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2).docx数据仓库解决方案v1.0 (2)....
  • 数据流图、数据字典

    2022-05-16 15:38:02
      文章目录数据流图的基本图形元素       数据流图也称为数据流程图(Data...  数据流图的基本图形元素包括数据流(Data Flow)、加工(Process)、数据存储(Data Store)和外部实体(External A
  • 大数据--数据仓库

    千次阅读 2022-04-24 15:39:49
    数据库(Database):按照一定格式和数据结构计算机保存数据的软件,属于物理层。 最早期是广义上的数据库,这个阶段的数据库结构主要以层次或网状的为主,这是数据库的数据和程序间具备非常强的依赖性,应用有...
  • 数据仓库简介

    2021-06-19 01:13:01
    数据仓库一、什么是数据仓库二、操作型系统和分析型系统1.操作型系统2.分析型系统3.操作型系统与分析型系统对比三、数据仓库架构1.基本架构2.主要的数据仓库架构 一、什么是数据仓库 数据仓库是一个面向主题的、集成...
  • 本任务使用 Python 来获取豆瓣网某电影下所有的评论,进行分析,从观 众的角度来了解这部电视剧。 数据获取 使用如下脚本获取时间,星级,评论 正则表达式可此处测试正则表达式可视化工具和正则表达式调试工具 ...
  • 数据仓库的概念有了基本的认识后,有必要单独说明一下ETL这个最重要的过程,然后向读者介绍四种常见的数据仓库架构。本篇最后描述实时数据仓库的产生背景、特定需求和使用场景,并列举一些常见的实时数据仓库...
  • 第二章 数据仓库
  • 数据仓库与数据挖掘

    千次阅读 2022-01-09 17:06:58
    数据挖掘:大量的数据中心挖掘感兴趣的知识、规则、规律、模式、约束(分析)。 数据仓库用于决策分析: 数据仓库:是数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,并不是...
  • 1.数据仓库简介 1.1什么是数据仓库 本质上,数据仓库试图提供一种从操作型系统到决策支持环境的数据流架构模型。...缓解事务处理数据库上因执行大查询而产生的资源竞争问题。 维护历史数据。 通过对多个源
  • 数据仓库与数据挖掘课后思考题整理 文章目录数据仓库与数据挖掘课后思考题整理1 数据仓库概述思考题2 数据仓库及其设计思考题实践题3 OLAP...主题是指用户使用数据仓库进行决策时所关心的重点领域,也就是一个较高的
  • 清单上传 如果您需要更多的灵活性...请参阅此 Colab 笔记本的完整示例,该示例演示使用清单将图像图块作为单个资产上传。 一次性设置 清单上传仅适用于位于Google Cloud Storage 的文件。要开始使用 Goo...
  • 数据治理概述

    千次阅读 2021-08-31 10:50:34
    学习数据治理知识之前,首先要明白治理的对象都有哪些,什么才是数据?是1,2,3,4这种纯数字类型的才算数据吗?还是所有的文本数据都是数据? 请往下看。 1.1 元数据数据元、数据源、源数据数据数据元...
  • XX数据中心技术方案

    千次阅读 2020-11-15 22:49:45
    系统建设目标 建设背景 监管背景 2016年12月30日颁布的《证券公司全面风险管理规范》要求当中,首次提出“证券公司应当建立健全数据治理和质量控制机制。...证券公司金融市场上发挥着日益重要的作用,也面..
  • 数据仓库架构和建设方法论

    千次阅读 2020-11-05 09:36:29
    建设数据仓库之前,数据散落企业各部门应用的数据存储,它们之间有着复杂的业务连接关系,从整体上看就如一张巨大的蜘蛛网:结构上错综复杂,却又四通八达。企业级数据应用上单一业务使用方便,且灵活多变;...
  • android蓝牙传输数据 要开发通过蓝牙(BT)进行数据传输的Android应用程序,请从逻辑上从Android开发人员的蓝牙页面开始,该页面详细描述了所有必需的步骤:设备发现,配对,客户端/服务器套接字,RFCOMM通道,等等 ...
  • 如何利用SVD简化数据

    2022-05-04 11:39:55
    如何利用SVD简化数据
  • 第一章 数据仓库概述 1.1 数据仓库简介 1.1.2 什么是数据仓库? 1.1.3 OLTP 与 OLAP 1.2 数据仓库技术架构 1.3 课程目标 第二章 核心技术框架 2.1 数据仓库周边技术框架 2.1.2 数据采集 Datax Sqoop Datax 与 Sqoop...
  • 文章目录MySQL操作表中数据MySQL 数据表查询语句查询表所有字段使用“*”查询表的所有字段列出表的所有字段查询表指定的字段MySQL过滤重复数据MySQL 设置别名为表指定别名为字段指定别名MySQL限制查询结果的条数...
  • 数据仓库建设

    2021-04-28 13:35:40
    建设数据仓库之前,数据散落企业各部门应用的数据存储,它们之间有着复杂的业务连接关系,从整体上看就如一张巨大的蜘蛛网:结构上错综复杂,却又四通八达。企业级数据应用上单一业务使用方便,且灵活多变;...
  • 经过近两年的数据湖建设,目前已经完成1.2万个逻辑数据实体、28万个业务属性的入湖,同时数据入湖华为公司也形成了标准的流程规范,每个数据资产都要入湖成为数据工作的重要标准。 华为数据湖主要有以下几个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,440
精华内容 1,776
关键字:

在数据清单中的行代表