一、数仓基本介绍
1.1、数仓基本概念
英文名称为Data Warehouse,可简写为DW或DWH。数据仓库的目的是构建面向分析的集成化数据环境,为企业提供决策支持(Decision Support)。它出于分析性报告和决策支持目的而创建。
数据仓库本身并不“生产”任何数据,同时自身也不需要“消费”任何的数据,数据来源于外部,并且开放给外部应用,这也是为什么叫“仓库”,而不叫“工厂”的原因。
通俗理解,收集大量数据,进行分析,为管理层提供解决方案和系统数据支持
通俗的讲,比如一个电商app,收集了大量的用户信息,购买信息,就会通过用户的购买行为去分析出,用户爱买什么想要买什么,什么样的人群会买什么样的商品,进行精准的定位,实现利益最大化。
数据仓库存放大量数据,低密度价值,成体积之后才能体现出价值

1.2、数仓的定义
数据仓库是面向主题的(Subject-Oriented )、集成的(Integrated)、稳定性的(Non-Volatile)和时变的(Time-Variant )数据集合,用以支持管理决策。
1.2.1、面向主题
数据仓库中的数据是按照一定的主题域进行组织。
主题是一个抽象的概念,是指用户使用数据仓库进行决策时所关心的重点方面,一个主题通常与多个操作型信息系统相关。
1.2.2、集成性
根据决策分析的要求,将分散于各处的源数据进行抽取、筛选、清理、综合等工作,最终集成到数据仓库中。
1.2.3、稳定性
数据的相对稳定性,数据仓库中的数据只进行新增,没有更新操作、删除操作处理。
反映历史变化,以查询分析为主。
1.2.4、时变性
数据仓库的数据一般都带有时间属性,随着时间的推移而发生变化,不断地生成主题的新快照
1.3、数据仓库与数据库的区别
数据库与数据仓库的区别实际讲的是 OLTP 与 OLAP 的区别。
OLTP: On-Line Transaction Processing 叫联机事务处理, 也可以称面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传统的数据库系统作为数据管理的主要手段,主要用于操作型处理 .
OLAP:On-Line Analytical Processing 叫联机分析处理,一般针对某些主题的历史数据进行分析,支持管理决策。
简而言之,数据库是面向事务的设计,数据仓库是面向主题设计的。
数据库一般存储在线交易数据,有很高的事务要求;数据仓库存储的一般是历史数据。
数据库设计是尽量避免冗余,一般采用符合范式的规则来设计,数据仓库在设计是有意引入冗余,采用反范式的方式来设计。
数据库是为捕获数据而设计,数据仓库是为分析数据而设计,它的两个基本的元素是维表和事实表。维是看问题的角度,比如时间,部门,维表放的就是这些东西的定义,事实表里放着要查询的数据,同时有维的ID。
| 功能 | 数据仓库 | 数据库 |
|---|---|---|
| 数据范围 | 存储历史的、完整的、反应历史变化的 | 当前状态数据 |
| 数据变化 | 可添加、无删除、无变更的、反应历史变化 | 支持频繁的增、删、改、查操作 |
| 应用场景 | 面向分析、支持战略决策 | 面向业务交易流程 |
| 设计理论 | 违范式、适当冗余 | 遵照范式(第一、二、三等范式)、避免冗余 |
| 处理量 | 非频繁、大批量、高吞吐、有延迟 | 频繁、小批次、高并发、低延迟 |
1.4、构建数仓常用手段
• 传统数仓建设更多的基于成熟的商业数据集成平台,比如Teradata、Oracle、Informatica等,技术体系比较成熟完善,但相对比较封闭,对实施者技术面要求也相对专业且单一,一般更多应用于银行、保险、电信等“有钱”行业.
• 基于大数据的数仓建设一般是基于非商业、开源的技术,常见的是基于hadoop生态构建,涉及技术较广泛、复杂,同时相对于商业产品,稳定性、服务支撑较弱,需要自己维护更多的技术框架。在大数据领域,常用的数据仓库构建手段很多基于hive,sparkSQL,impala等各种技术框架.
1.5、数仓分层
1.5.1、数仓分层描述
- 数据仓库更多代表的是一种对数据的管理和使用的方式,它是一整套包括了etl、调度、建模在内的完整的理论体系。现在所谓的大数据更多的是一种数据量级的增大和工具的上的更新。 两者并无冲突,相反,而是一种更好的结合。数据仓库在构建过程中通常都需要进行分层处理。业务不同,分层的技术处理手段也不同。
- 分层是数据仓库解决方案中,数据架构设计的一种数据逻辑结构 ,通过分层理念建立的数据仓库,它的可扩展性非常好,这样设计出来的模型架构,可以任意地增减、替换数据仓库中的各个组成部分。

从整体的逻辑划分来讲,数据仓库模型实际上就是这三层架构。
接入层:底层的数据源或者是操作数据层,一般在公司的话,统一都是称为ODS层
中间层:是做数据仓库同学需要花费更多精力的一层,这一层包括的内容是最多的、最复杂的。
应用层:对不同的应用提供对应的数据。该层主要是提供数据产品和数据分析使用的数据,比如我们经常说的报表数据
- 针对于这三层架构,这里给出比较典型的一个做数据仓库在实施的时候,具体的层次划分。

- ODS:
- Operation Data Store 原始数据层
- 不对数据进行过多处理,只做轻度的处理,保存原始数据基本结构
- DWD
- data warehouse detail 数据明细层
- 它主要是针对于接入层的数据进行数据的清洗和转换。还有就是一些维度的补充。
- 进行清洗(去空,去脏,取出明显不符合要求的数据,结构和粒度跟原始数据保持一致)
- DWS
- data warehouse summary 数据汇总层
- 它是在DWD明细层之上,也有公司叫DW层
- 它是按照一定的粒度进行了汇总聚合操作。它是单业务场景。
- DWM
- data warehouse market 数据集市层
- 它是在DWS数据汇总层之上,集市层它是多业务场景的。
- APP
- Application 应用层
- 这个是数据仓库的最后一层数据,为应用层数据,直接可以给业务人员使用。
TMP临时表:在做一些中间层表计算的时候,大量使用tmp临时表。
DIM维度层:基于ODS层和DWD层抽象出一些公共的维度,典型的公共维度主要包括城市信息、渠道信息、个人基础属性信息。
1.5.2、为什么要进行数仓分层
因为原始数据人看不懂,老板看不懂,决策者也看不懂,需要我们去梳理,去清洗,去进行价值提取
分层的主要原因是在管理数据的时候,能对数据有一个更加清晰的掌控,主要有下面几个原因:
- 空间换时间
- 通过建设多层次的数据模型供用户使用,避免用户直接使用底层操作型数据,可以更高效的访问数据。
- 把复杂问题简单化
- 将一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性,当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。
- 便于处理业务的变化
- 随着业务的变化,只需要调整底层的数据,对应用层对业务的调整零感知。
- 清晰数据结构
- 每一个数据分层都有它的作用域,这样我们在使用表的时候能更方便地定位和理解。
- 数据血缘追踪
- 简单来说,我们最终给业务呈现的是一个能直接使用业务表,但是它的来源有很多,如果有一张来源表出问题了,我们希望能够快速准确地定位到问题,并清楚它的危害范围。
- 减少重复开发
- 规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。
- 屏蔽原始数据的异常
- 屏蔽业务的影响,不必改一次业务就需要重新接入数据
1.6、获取数据
日志:flume等
落地到磁盘
前端埋点数据
移动端埋点
业务:导入导出工具 datax sqoop canal
数据库中的数据
爬虫:python直接写入到hdfs
爬取精品数据
- 什么是埋点
所谓“埋点”,是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。将数据写入到日志文件(落盘)
1.7、同步策略
全量表:存储完整的数据。
增量表:存储新增加的数据。
新增及变化表:存储新增加的数据和变化的数据。
拉链表:对新增及变化表做定期合并。
- 实体表同步策略
比如用户,商品,商家
实体表数据量比较小,通常可以做每日全量,每天保存一份数据,即为每日全量
- 维度表同步策略
订单状态,审批状态,商品分类
比如撤销订单,审批失败这种作为每日全量进行同步
但是比如民族国家地区省事这些作为一份固定值
二、数据仓库建模
目前业界较为流行的数据仓库的建模方法非常多,这里主要介绍范式建模法,维度建模法,实体建模法等几种方法,每种方法其实从本质上讲就是从不同的角度看我们业务中的问题,不管从技术层面还是业务层面,其实代表的是哲学上的一种世界观。
2.1、范式建模法(Third Normal Form 3NF)
范式建模法是基于整个关系型数据库的理论基础之上发展而来的,其实是我们在构建数据模型常用的一个方法,主要解决关系型数据库得数据存储,利用的一种技术层面上的方法。目前,我们在关系型数据库中的建模方法,大部分采用的是三范式建模法。
从其表达的含义来看,一个符合第三范式的关系必须具有以下三个条件 :
(1)每个属性值唯一,不具有多义性 ;
(2)每个非主属性必须完全依赖于整个主键,而非主键的一部分 ;
(3)每个非主属性不能依赖于其他关系中的属性,因为这样的话,这种属性应该归到其他关系中去。
2.2、维度建模法
维度建模(dimensional modeling)是专门用于分析型数据库、数据仓库、数据集市建模的方法。维度建模法简单描述就是按照事实表、维度表来构建数仓、集市。
维度建模从分析决策的需求出发构建模型,为分析需求服务,因此它重点关注用户如何更快速地完成需求分析,同时具有较好的大规模复杂查询的相应性能。
2.2.1、维度表
维度表是你要对数据进行分析时所用的一个量,比如你要分析产品销售情况, 你可以选择按类别来进行分析,或按区域来分析。
通常来说维度表信息比较固定,且数据量小
一般是指对应一些业务状态,编号的解释表。也可以称之为码表。
地区表,订单状态,支付方式,审批状态,商品分类
2.2.2、事实表
表示对分析主题的度量。
事实表包含了与各维度表相关联的外键,并通过join方式与维度表关联。事实表的度量通常是数值类型,且记录数会不断增加,表规模迅速增长。
消费事实表:Prod_id(引用商品维度表), TimeKey(引用时间维度表), Place_id(引用地点维度表), Unit(销售量)。
总的说来,在数据仓库中不需要严格遵守规范化设计原则。因为数据仓库的主导功能就是面向分析,以查询为主,不涉及数据更新操作。事实表的设计是以能够正确记录历史信息为准则,维度表的设计是以能够以合适的角度来聚合主题内容为准则
一般是指一个现实存在的业务对象,比如用户,商品,商家,销售员等等
2.2.3、维度建模三种模式
基于事实表和维表就可以构建出多种多维模型,包括星形模型、雪花模型和星座模型。
维度建模法最被人广泛知晓的名字就是星型模式。
- 星型模式
星形模式(Star Schema)是最常用的维度建模方式。星型模式是以事实表为中心,所有的维度表直接连接在事实表上,像星星一样。
星形模式的维度建模由一个事实表和一组维表成,且具有以下特点:
a. 维表只和事实表关联,维表之间没有关联;
b. 每个维表主键为单列,且该主键放置在事实表中,作为两边连接的外键;
c. 以事实表为核心,维表围绕核心呈星形分布;
- 雪花模式
雪花模式是对星形模式的扩展。雪花模式的维度表可以拥有其他维度表的,虽然这种模型相比星型更规范一些,但是由于这种模型不太容易理解,维护成本比较高,而且性能方面需要关联多层维表,性能也比星型模型要低。所以一般不是很常用。
星座模式是星型模式延伸而来,星型模式是基于一张事实表的,而星座模式是基于多张事实表的,而且共享维度信息。
前面介绍的两种维度建模方法都是多维表对应单事实表,但在很多时候维度空间内的事实表不止一个,而一个维表也可能被多个事实表用到。在业务发展后期,绝大部分维度建模都采用的是星座模式。
2.3、实体建模法
实体建模法并不是数据仓库建模中常见的一个方法,它来源于哲学的一个流派。
从哲学的意义上说,客观世界应该是可以细分的,客观世界应该可以分成由一个个实体,以及实体与实体之间的关系组成。
那么我们在数据仓库的建模过程中完全可以引入这个抽象的方法,将整个业务也可以划分成一个个的实体,而每个实体之间的关系,以及针对这些关系的说明就是我们数据建模需要做的工作。
参考文档:http://www.uml.org.cn/sjjmck/201810163.asp
三、数据仓库架构

3.1、数据采集
数据采集层的任务就是把数据从各种数据源中采集和存储到数据存储上,期间有可能会做一些ETL操作。
数据源种类可以有多种:
日志:所占份额最大,存储在备份服务器上
业务数据库:如Mysql、Oracle
来自HTTP/FTP的数据:合作伙伴提供的接口
其他数据源:如Excel等需要手工录入的数据
3.2、数据存储与分析
HDFS是大数据环境下数据仓库/数据平台最完美的数据存储解决方案。
离线数据分析与计算,也就是对实时性要求不高的部分,Hive是不错的选择。
使用Hadoop框架自然而然也提供了MapReduce接口,如果真的很乐意开发Java,或者对SQL不熟,那么也可以使用MapReduce来做分析与计算。
Spark性能比MapReduce好很多,同时使用SparkSQL操作Hive。
3.3、数据共享
前面使用Hive、MR、Spark、SparkSQL分析和计算的结果,还是在HDFS上,但大多业务和应用不可能直接从HDFS上获取数据,那么就需要一个数据共享的地方,使得各业务和产品能方便的获取数据。
这里的数据共享,其实指的是前面数据分析与计算后的结果存放的地方,其实就是关系型数据库和NOSQL数据库。
3.4、数据应用
报表:报表所使用的数据,一般也是已经统计汇总好的,存放于数据共享层。
接口:接口的数据都是直接查询数据共享层即可得到。
即席查询:即席查询通常是现有的报表和数据共享层的数据并不能满足需求,需要从数据存储层直接查询。一般都是通过直接操作SQL得到。
四、理想的数仓架

增加以下内容
- 数据采集
- 采用Flume收集日志,采用Sqoop将RDBMS以及NoSQL中的数据同步到HDFS上
- 消息系统
- 可以加入Kafka分布式消息系统保证数据丢失
- 机器学习
- 使用了SparkMLlib提供的机器学习算法
- 数据可视化
- 提供可视化前端页面,方便运营等非开发人员直接查询
- 任务调度和监控
- 任务的统一调度和监控
五、技术选型
数据采集:flume kafka sqoop datax
数据存储:mysql hdfs hbase redis
数据计算:hive spark flink
数据查询:impala kylin


六、小栗子
6.1、用户行为日志
{"app":"xxxxx",//项目数据来源 app pc
"common": { //公共字段
"mid": "", // (String) 设备唯一标识
"uid": "", // (String) 用户标识
"vc": "1", // (String) versionCode,程序版本号
"vn": "1.0", // (String) versionName,程序版本名
"l": "zh", // (String) 系统语言
"sr": "", // (String) 渠道号,应用从哪个渠道来的。
"os": "7.1.1", // (String) Android系统版本
"ar": "CN", // (String) 区域
"md": "BBB100-1", // (String) 手机型号
"ba": "apple", // (String) 手机品牌
"sv": "13", // (String) sdkVersion
"g": "", // (String) gmail
"t": "1506047606608", // (String) 客户端日志产生时的时间
"nw": "WIFI", // (String) 网络模式
},
"event": [ //事件
{
"e_time": "1506047605364", //事件时间
"e_name": "display", //事件名称
"e_result": { //事件结果,以key-value形式自行定义
"goodsid": "1111",
"action": "2",
"extend1": "3",
"place": "4",
"category": "75"
}
}
]
}

- 页面
action 动作:曝光商品=1, 加载成功=2,加载失败=3
loading_time 加载时长:点击商品进入页面所用时间
loading_way 加载类型:1-读取缓存,2-从接口拉新数据 (加载成功才上报加载类型)
watchtime 浏览当前页面时间
actionType 打开方式(连接,搜索)
watchtype 加载类型:自动加载=1,用户下拽加载=2,底部加载=3(底部条触发点击底部提示条/点击返回顶部加载)
type1 加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败)
- 商品点击

事件标签:clickDisplay
action 动作:曝光商品=1,点击商品=2,
goodsid 商品ID(服务端下发的ID)
order 顺序(第几条商品,第一条为0,第二条为1,如此类推)
extend1 曝光类型:1 - 首次曝光 2-重复曝光
category 分类ID(服务端定义的分类ID)
- 广告
事件名称:advertisement
标签 含义
entry 入口:商品列表页=1 应用首页=2 商品详情页=3 在哪里看到广告的
action 动作:请求广告=1 取缓存广告=2 广告位展示=3 广告展示=4 广告点击=5
content 状态:成功=1 失败=2
detail 失败码(没有则上报空)
source 广告来源:
newstype Type: 1- 图文 2-图集 3-段子 4-GIF 5-视频 6-调查 7-纯文 8-视频+图文 9-GIF+图文 0-其他
show_style 内容样式:无图(纯文字)=6 一张大图=1 三站小图+文=4 一张小图=2 一张大图两张小图+文=3 图集+文 = 5
一张大图+文=11 GIF大图+文=12 视频(大图)+文 = 13

6.2、日志处理


Flume:过滤,拦截器,对数据进行过滤,多路数据归类
Kafka:使用不通topic去接收不同种类的数据,对数据进行分流
Hdfs:存储数据
Hive:接收清洗过的数据进行分层处理,提供业务支持
6.3、用户画像
- 女人

- 金融产品

- 头条

- 音乐


6.4、某电商数据建设整体架构
