day02_新零售课程笔记
今日内容:
- 1- 数仓建模 (理解)
- 2- 数仓分层架构 (理解)
- 3- 数仓的工具的基本使用 (掌握)
- 4- 业务数据的准备工作 (参考笔记处理即可)
1. 数仓建模
何为建模: 如何在数据仓库中构建表, 是一套用于规范化建表的理论
常见的数仓建模理论:
三范式建模:
主要是应用在传统的数据仓库中, 指的数据存储在关系型的数据库中, 要求在建表的时候, 表必须有主键 同时表中尽量的避免数据的冗余的发生, 尽可能拆分表
维度建模:
主要是应用于新型的数据仓库中, 指的数据存储在专门用于进行OLAP数据库中, 比如 要求建模的时候以分析为前提, 只要是利于分析的建模方案, 认为都是OK的, 在此情况下, 即使数据存在一定的冗余也是OK的
后续主要采用维度建模的思想来构建相关的表, 在维度建模中, 主要规定了两种表模型: 事实表 和 维度表
1.1 事实表
什么是事实表:
事实表: 指的主题,要统计的主题是什么, 对应事实就是什么, 而主题所对应的表, 其实事实表
事实表一般是一坨主键(其他表)的聚集
事实表一般是反应了用户某种行为表
比如说:
订单表, 收藏表, 登录表, 购物车表 ...
事实表分类:
事务事实表 : 最初始确定的事实表 其实就是事务事实表
累计快照事实表: 指的对数据进行提前聚合后表, 比如将事实表按照天聚合统计 结果表
周期快照事实表: 每一条数据, 记录了完整的事件 从开始 到结束整个流程, 一般有多个时间组成
1.2 维度表
什么是维度表:
维度表: 当对事实表进行统计分析的时候, 可能需要关联一些其他表进行辅助, 这些表其实就是维度表
维度表一般是由平台或者商家来构建的表, 与用户无关, 不会反应用户的行为
比如说: 地区表 商品表 时间表, 分类表...
维度表分类:
高基数维度表: 如果数据量达到几万 或者几十万 甚至几百万的数据量, 一般这样维度表称为高基数维度表
比如: 商品表 , 用户表
低基数维度表: 如果数据量只有几条 或者 几十条 或者几千条, 这样称为低基数维度表
比如: 地区表 时间表 分类表 配置表
1.3 数仓发展模型
数仓发展的三种模型:
- 星型模型:
- 特点: 只有一个事实表, 也就意味着只有一个分析的主题, 在事实表周围围绕了多张维度表, 维度表与维度表没有任何关联
- 数仓发展阶段: 初期
- 雪花模型:
- 特点: 只有一个事实表, 也就意味着只有一个分析的主题, 在事实表周围围绕了多张维度表, 维度表可以接着关联其他的维度表
- 数仓发展阶段: 异常, 出现畸形状态 在实际数仓中, 这种模型建议越少越好, 尽量避免这种模型产生
- 星座模型:
- 特点: 有多个事实表, 也就意味着有了多个分析的主题, 在事实表周围围绕了多张维度表, 在条件吻合的情况下, 事实表之间是可以共享维度表
- 数仓发展阶段: 中期 和 后期
图示演示:
1.4 缓慢渐变维
缓慢渐变维:
主要是用于解决历史变更问题, 处理历史变更的数据是否需要保留的问题
如何解决问题?
- SCD1: 不维护历史变更行为, 直接对过去数据进行覆盖即可
- 此种操作 仅适用于错误数据的处理
- SCD2: 维护历史变更行为, 处理方式 在表中新增两个新的字段, 一个是起始时间, 一个是结束时间, 当数据发生变更后, 将之前的数据设置为过期, 将新的变更后完整的数据添加到表中, 重新记录其起始和结束时间, 将这种方案称为 拉链表
- 好处: 可以维护更多的历史版本的数据, 处理起来也是比较简单的 (利于维护)
- 弊端: 造成数据冗余存储 大量占用磁盘空间
- SCD3: 维度历史变化, 处理方式, 当表中有字段发生变更后, 新增一列, 将变更后的数据存储到这一列中即可
- 好处: 减少数据冗余存储
- 弊端: 只能维护少量的历史版本, 而且维护不方便, 效率比较低
- 适用于: 空间比较紧缺,而且只需要维护少量版本的情况
2. 数仓分层介绍
回顾:
ODS: 源数据层(临时存储层)
作用: 对接数据源, 用于将数据源的数据完整的导入到ODS层中, 一般ODS层的数据和数据源的数据保持一致, 类似于一种数据迁移的操作, 一般在ODS层建表的时候, 会额外增加一个 日期的分区, 用于标记何时进行数据采集
DW: 数据仓库层
作用: 用于进行数据统计分析的操作, 数据来源于 ODS层
APP(DA|ADS | RPT |ST) : 数据应用层(数据展示层)
作用: 存储分析的结果信息, 用于对接相关的应用, 比如 BI图表
以新零售项目为例:
ODS层: 源数据层(临时存储层)
作用: 对接数据源, 用于将数据源的数据完整的导入到ODS层中, 一般ODS层的数据和数据源的数据保持一致, 类似于一种数据迁移的操作, 一般在ODS层建表的时候, 会额外增加一个 日期的分区, 用于标记何时进行数据采集
DW层: 数据仓库层
DWD层: 明细层
作用: 和ODS层保持相同的粒度,不会对数据进行聚合操作, 只要进行清洗 转换工作, 保证数据质量,利于后续分析
清洗: 过滤掉一些无用数据
转换: 格式转换 或者 一个字段 转换为多个字段, json转换....
DWB层: 基础数据层
作用: 进行维度退化的操作, 根据业务模块. 形成业务宽表
维度退化:
以订单表为例, 在订单表中, 有用户 id , 商品id 商家id, 地区的id信息. 如果统计需要按照用户, 商品, 商家 和地区来统计操作, 此时需要关联用户表, 商品表 商家表 地区表
维度退化:
提前先将这些维度表中可能需要使用字段合并到事实表中, 让事实表变的更宽,后续在统计的时候, 只需要关联订单表即可
DWS层: 业务数据层
作用: 用于进行提前聚合操作, 形成基础主题统计宽表指标数据
例如: 需求要求统计 每年 每月 每日的销售额. 那么在DWS层, 可以先按照日形成统计结果数据
DM层: 数据集市层
作用: 基于主题, 形成数据集市, 对指标进行细化统计过程
例如: 需要将 每年 每月 每日的销售额全部记录在DM层中, 此时我们只需要对DWS层进行上卷统计即可
APP(DA|ADS | RPT |ST) : 数据应用层(数据展示层)
作用: 存储分析的结果信息, 用于对接相关的应用, 比如 BI图表
3. 数仓工具基本使用
3.1 HUE基本使用
HUE: hadoop 用户 体验
HUE: 本质上就是大集成者, 将大数据中各种软件的操作界面 集成在一起, 通过HUE 完成对大数据相关的组件操作
如何进入HUE呢?
3.2 使用HUE操作HDFS
3.3 使用HUE操作HIVE
查看HIVE库的基本信息:
如何编写SQL呢?
3.4 使用 HUE 操作 oozie
oozie: 是一个工作流的调度工具, 实现对工作流的定时调度操作
何为工作流: 指“业务过程的部分或整体在计算机应用环境下的自动化”
工作流一般要满足以下几个特征:
1- 一个流程是可以被拆解为多个阶段(步骤)
2- 多个阶段之间存在依赖关系, 前序没有执行, 后续无法执行
3- 整个流程 需要周而复始不断的干
请问, 大数据的工作流程是否可以使用工作流解决呢?
先回答: 大数据的工作流程有那些呢?
1- 确定数据源
2- 数据的存储
3- 数据的预处理
4- 数据的分析处理
5- 数据的应用
所以说大数据可以使用工作流解决问题的
能够实现工作流的大数据组件有那些?
oozie:
是apache旗下一款工作流的调度工具, 出现时间也是比较久的, oozie如果单独使用, 是非常麻烦的, 提供的管理界面仅仅只能查看一些状态, 无法对工作流进行操作, 所有的操作都需要通过配置 XML文档, 整个配置非常复杂的
但是由于人家apache 大数据 全家桶一员, HUE在集成一款调度工具, 优先选择自家产品, 使用HUE, 只需要用户通过鼠标点一点即可完成oozie工作流的配置了
azkaban:
属于领英公司旗下一款的工作流的调度工具, 开源免费的, azkaban简单来说就是一个shell脚本调度工具, 提供了同一个工作流的界面,可以直接在界面上提交工作流 ,并对工作流进行监控, 整个工作流的配置, 仅需要简单配置几行类似于properties文件即可完成
单独使用角度: azkaban
如果结合HUE: oozie
如何使用oozie:
- 1- 开启 HUE 对 oozie的支持
- 2- 重启 HUE , 实现配置生效
- 查看HUE界面:
如何配置工作流:
查看输出结果:
如何配置定时:
3.5 sqoop的基本使用操作
sqoop是apache旗下顶级项目. 主要是用于 RDBMS 和 大数据生态圈之间的数据导入导出的工具, 从RDBMS 到大数据生态圈 是导入操作, 反之为导出操作
sqoop本质上也是一款翻译软件, 将sqoop的命令翻译为 MR程序
关于使用sqoop 将数据导入到HIVE, 支持两种导入方案: 原生导入方案 和 hcatalog方式
区别点:
如果使用原生导入方式, 导入HIVE , 仅支持 textFile导入方式
hcatalog支持数据存储方案比较多: textFile, ORC, sequence, parquet....
原生方式支持数据覆盖导入
hcatalog仅支持追加导入
原生方式在导入时候, 根据字段的顺序, 导入到HIVE中
hcatalog在导入的时候, 是根据字段的名称导入的
(此部分建议在导入到HIVE , hive表字段的顺序 和 mysql表字段顺序保持一致, 名称保持一致)
后续主要采用 hcatalog的导入方式, 因为建表的时候, 主要存储格式为 ORC
3.5.1 基本使用操作
- 1- 如何查看 sqoop的 帮助文档
sqoop help
如何查看某个操作下的相关的参数信息:
sqoop 操作 --help
- 2- 查询mysql中所有的库有那些?
思考: 连接mysql需要知道什么信息呢?
1- 用户名 2- 密码 3- 连接地址
sqoop list-databases --connect jdbc:mysql://hadoop01:3306 --username root --password 123456
- 3- 查询mysql中scm中所有的表
sqoop list-tables \
--connect jdbc:mysql://hadoop01:3306/scm \
--username root \
--password 123456
\ : 未完待续
3.5.2 数据全量导入操作
准备工作:
create database test default character set utf8mb4 collate utf8mb4_unicode_ci;
use test;
create table emp
(
id int not null
primary key,
name varchar(32) null,
deg varchar(32) null,
salary int null,
dept varchar(32) null
);
INSERT INTO emp (id, name, deg, salary, dept) VALUES (1201, 'gopal', 'manager', 50000, 'TP');
INSERT INTO emp (id, name, deg, salary, dept) VALUES (1202, 'manisha', 'Proof reader', 50000, 'TP');
INSERT INTO emp (id, name, deg, salary, dept) VALUES (1203, 'khalil', 'php dev', 30000, 'AC');
INSERT INTO emp (id, name, deg, salary, dept) VALUES (1204, 'prasanth', 'php dev', 30000, 'AC');
INSERT INTO emp (id, name, deg, salary, dept) VALUES (1205, 'kranthi', 'admin', 20000, 'TP');
create table emp_add
(
id int not null
primary key,
hno varchar(32) null,
street varchar(32) null,
city varchar(32) null
);
INSERT INTO emp_add (id, hno, street, city) VALUES (1201, '288A', 'vgiri', 'jublee');
INSERT INTO emp_add (id, hno, street, city) VALUES (1202, '108I', 'aoc', 'sec-bad');
INSERT INTO emp_add (id, hno, street, city) VALUES (1203, '144Z', 'pgutta', 'hyd');
INSERT INTO emp_add (id, hno, street, city) VALUES (1204, '78B', 'old city', 'sec-bad');
INSERT INTO emp_add (id, hno, street, city) VALUES (1205, '720X', 'hitec', 'sec-bad');
create table emp_conn
(
id int not null
primary key,
phno varchar(32) null,
email varchar(32) null
);
INSERT INTO emp_conn (id, phno, email) VALUES (1201, '2356742', 'gopal@tp.com');
INSERT INTO emp_conn (id, phno, email) VALUES (1202, '1661663', 'manisha@tp.com');
INSERT INTO emp_conn (id, phno, email) VALUES (1203, '8887776', 'khalil@ac.com');
INSERT INTO emp_conn (id, phno, email) VALUES (1204, '9988774', 'prasanth@ac.com');
INSERT INTO emp_conn (id, phno, email) VALUES (1205, '1231231', 'kranthi@tp.com');
- 如何全量将数据导入到HDFS中:
- 需求一: 将 emp表中数据导入到HDFS中
需要知道什么信息? 数据库的基本信息(连接地址, 用户名, 密码, 表名) 目的地的路径信息
方式一:
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username root \
--password 123456 \
--table emp
说明:
1- 当不指定导出路径的时候, 默认会将数据导入到当前操作用户的HDFS的家目录下, 再次目录下以表名创建一个文件夹, 将数据放置到这个文件夹中
2- 发现在导入数据的时候, 有多少条数据, 就会运行多少个mapTask, 最高和cpu核数相等
3- 数据之间的分隔符号为 逗号
思考: 是否可以将其导入到其他位置呢? --target-dir 和 --delete-target-dir
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username root \
--password 123456 \
--table emp \
--delete-target-dir \
--target-dir /sqoop_works/emp
说明:
--target-dir : 将数据导入到HDFS的那个位置中
--delete-target-dir: 如果目的地路径以存在, 先删除
思考: 是否可以设置其mapTask的数量呢? -m 和 --split-by
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username root \
--password 123456 \
--table emp \
--delete-target-dir \
--target-dir /sqoop_works/emp \
-m 2 \
--split-by id
说明:
如果 -m为1 , 表示只允许一个mapTask, 此时可能省略 --split-by
--split-by 表示按照那个字段进行切割数据表, 一般设置为主键字段, 如果主键字段是多个, 那么就写多个, 用逗号隔开
思考: 是否可以调整分隔符号呢? 比如说 设置为 | 参数: --fields-terminated-by
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username root \
--password 123456 \
--table emp \
--delete-target-dir \
--target-dir /sqoop_works/emp \
--fields-terminated-by '|' \
-m 1