ODS 层因为保留原始数据, 所以和业务数据库 (关系模型) 一样是关系模型.
DWD 层即进行了维度建模, 将下面的模型 ↓
转化为了下面的维度模型, 即以事实表为中心, 周围有一圈的维度表 ↓
维度模型中的表数据 (数据特征) 可能有冗余, 但查询时一般只需要进行事实表和维度表进行 join, 不用 join 太多表, 查询性能更好.
在维度建模的基础上又分为三种模型:星型模型、雪花模型、星座模型。
但生产中事实表不可能只有一张, 所以多个事实表多个维度表结合形成了星座模型:
select 维度 agg(事实) from table group by 维度
.维度模型对数据关系的变化也具有很高的适应性. 当发生以下变化时, 不需要改变现存的 BI 查询或应用, 就可以方便地适应, 且查询结果不会有任何改变:
如果, DW 采用了星型模式建模, 或 OLAP 建模, 都可以说是利用了维度的概念, 他们对维度的认识是一样的, 只是物理实现上不一样. OLAP 一般用于即席查询, 通常会进行与计算, 索引策略和其他的优化方法; 同时有很多比 SQL 更好的分析函数, 使得OLAP的查询和分析性能更好, 不需要提出新的查询.
但是, 一般在 OLAP 之前, 我们还是会将详细的, 原子的信息加载到星型模型中, 然后由此建立 OLAP 分析模型.
星型模型主要包含事实表, 以及通过主键/外键关系与之关联的维度表, 联机分析处理 ( OLAP) 多维数据库是实现在多维数据库之上的多维结构, 它与星型模型内容等价, 或者说来源于星型模型.
OLAP 多维数据库也是包含维度属性和事实表, 但它能够使用比 SQL 语言具有更强的分析能力的语言访问, 比如 XMLA 和 MDX 等.
OLAP 多维数据库通常是部署 DW/BI 的最后步骤, 或者作为基于多个原子关系型模式的聚集结构.
事实表中的每行数据代表一个业务事件或业务度量, 比如下单, 支付, 退款, 评价等.
事实表一般包含两部分字段:
事实表的特征:
最终计算通常在 DW 的上层或 OLAP 多维数据库层.
最主要是数值类型和可加类型:
这些都可以按照某些维度, 比如时间维度进行聚合, 这是最关键的.
半可加度量可以对某些维度进行汇总, 但不能对所有维度进行汇总.
比如, 差额是常见的半可加事实, 除了时间维度外, 他们可以跨所有维度进行加法操作.
比率是最常见的不可加度量.
一般对于这种, 非可加度量一般拆解为其全完可加分量.
事实表中每行数据是一个特定级别的细节数据, 称为粒度. 同一张事实表的粒度相同, 不会出现重复计算度量的问题.
最常见, 最典型的事实表. 它和上面介绍的事实表的基本描述是一样的.
以每个事务或事件为单位,例如一个销售订单记录,一笔支付记录等,作为事实表里的一行数据。一旦事务被提交,事实表数据被插入,数据就不再进行更改,其更新方式为增量更新。
特点:
有些可能没有可以记录的数字化事实, 比如:
比如日志数据, 一般也可以转换成无事实事实表.
周期型快照事实表中不会保留所有数据 (这句话是跟事务型事实表进行对比的),只保留固定时间间隔的数据,例如每天或者每月的销售额,或每月的账户余额, 或者加购物车事实表。
比如加购物车事实表:
最原子性的事件是加购物车和取消购物车, 但我们并不关注加减的过程或加了几次, 减了几次, 我们关注的是购物车中剩下的商品, 这些商品可能就是用户想买却舍不得买的商品, 这样我们就可以对其进行一个促销, 让大量用户进行购买, 这是我们关注的.
而购物车中的商品每天都可能会有变化, 所以我们一般周期性地记录购物车中的数据.
数仓中的具体实践是在 Hive 中建立日期为分区的购物车事实表, 然后 MySql 中的购物车表每天固定时间导入到 Hive 的当天日期分区中, 也就是每天打一个快照.
特点:
累计快照事实表用于跟踪业务事实的变化。例如,数据仓库中可能需要累积或者存储订单从下订单开始,到订单商品被打包、运输、和签收的各个业务阶段的时间点数据, 来跟踪订单生命周期的进展情况。
当这个业务过程进行时,事实表的记录也要不断更新。也就是一行数据没办法一次写完, 需要分多个阶段累计写完的, 每个阶段都是一个里程碑.
订单id | 用户id | 下单时间 | 打包时间 | 发货时间 | 签收时间 | 订单金额 |
---|---|---|---|---|---|---|
3-8 | 3-8 | 3-9 | 3-10 |
特点:
维度表: 一般是对事实的描述信息. 每一张维表对应现实世界中的一个对象或者概念. 例如: 用户, 商品, 日期, 地区等.
数仓的好坏取决于维度的设置, 分析能力取决于维度的质量和深度.
属性应该包含真实使用的词汇, 而不是令人感到迷惑的缩写, 尽量少使用代码, 而是使用文本.
有的操作码有确定的业务含义, 比如前两位表示业务类别, 3~4位表示区域, 与其用户查询过滤操作码, 不如前期就将操作码差分, 然后以不同维度展现给用户, 这样用户就能方便地展开过滤, 分组和制作报表等工作. 其实就是一个 ETL 的过程.
在分析操作码时, 如何确定某些元素是维度还是事实?
日期ID | day of week | day of year | 季度 | 节假日 |
---|---|---|---|---|
2020-01-01 | 2 | 1 | 1 | 元旦 |
2020-01-02 | 3 | 2 | 1 | 无 |
2020-01-03 | 4 | 3 | 1 | 无 |
2020-01-04 | 5 | 4 | 1 | 无 |
2020-01-05 | 6 | 5 | 1 | 无 |
ETL + 维度建模.
日志数据在 DWD 层按照内容解析, 分为 5 类, 解析成 5 张表: 页面, 曝光, 事件操作, 启动, 错误.
这里用到自定义解析 json 的函数.
DWD层需构建维度模型,一般采用星型模型,呈现的状态一般为星座模型。
选择业务过程→声明粒度→确认维度→确认事实
在业务系统中,挑选我们感兴趣的业务线,比如下单业务,支付业务,退款业务,物流业务,一条业务线对应一张事实表。
尽可能全地选择业务, 以应对后续业务需求的变更.
数据粒度指数据仓库的数据表中保存数据的细化程度或综合程度的级别。
一张事实表需要确定一个表的粒度, 即声明粒度意味着精确定义事实表中的一行数据表示什么,应该尽可能选择最细粒度,以此来应各种各样的需求。
为什么选择最细粒度? 我们从 DWD 层进行聚合时是从最小粒度开始聚合的, 最小粒度可以聚合为更粗的粒度, 但反之只有粗粒度是无法得到细粒度的. 所以有了最小粒度就意味着可以聚合得到各种粒度.
典型的粒度声明如下:
维度的主要作用是描述业务事实,主要表示的是 “谁,何处,何时” 等信息。
实际上就是确定事实表中有哪些外键.
一般就是先把所有维度列出来, 然后看每个事实表和哪些维度 (group by 的字段) 有关.
此处的 “事实” 一词,指的是业务中的度量值,例如
订单金额、下单次数, 单价, 折扣, 净支付价格等。
在 DWD 层,以 业务过程为建模驱动,基于每个具体业务过程的特点,构建最细粒度的明细层事实表。事实表可做适当的宽表化处理。
粒度 | 时间 | 用户 | 地区 | 商品 | 优惠券 | 活动 | 编码 | 快递商 | 仓库 | 度量值 | |
---|---|---|---|---|---|---|---|---|---|---|---|
订单 | 一条订单 | √ | √ | √ | √ | 件数/金额 | |||||
订单详情 | 订单中一件商品 | √ | √ | √ | 件数/金额 | ||||||
支付 | 一条支付记录 | √ | √ | 金额 | |||||||
加购物车 | 一个购物车记录 | √ | √ | √ | 件数/金额 | ||||||
收藏 | 用户一次收藏 | √ | √ | √ | 个数 | ||||||
评价 | 一次评价 | √ | √ | √ | 个数 | ||||||
退款 | 一次款款记录 | √ | √ | √ | 件数/金额 | ||||||
优惠券领用 | 一个用户领一个券的记录 | √ | √ | √ | 个数 |
这些关系是比较灵活的, 但前提是能关联上的, 能关联上的尽量关联上.
什么是能关联上? 一般关系模型的一张事实表中的维度外键是直接关联上的, 但还有一些是可以间接关联上的. 比如支付表和位置, 直接关联不上, 但支付和订单相关, 订单和位置相关, 这样就关联起来了.
至此,数仓的维度建模已经完毕,DWS、DWT 和 ADS 和维度建模已经没有关系了。
DWS 和 DWT 都是建宽表,宽表都是按照主题去建。主题相当于观察问题的角度。对应着维度表。
这两层是款表层.
统计各个主题对象的当天行为,服务于 DWT 层的主题宽表。
以分析的主题对象为建模驱动,基于上层的应用和产品的指标需求,构建主题对象的全量宽表。
DWS 和 DWT 都一定程度进行了聚合, 没有 DWS 和 DWT 层可以吗? 可以, 但是:
所以 DWS 和 DWT 层存在的意义就是减少数据重复计算, 提高数据的复用性, 优化数仓性能.
举例, 有以下需求:
1 统计今天每个省份订单的个数是多少?
select province, count(*) from orderInfo group by province where dt = 'xxxx-xx-xx'
2 统计今天每个省份下单的总金额是多少?
select province, sum(amount) from orderInfo group by procince where dt = 'xxxx-xx-xx'
这两个需求其实是类似的, 但如果从 DWD 来查询, 重复计算了两遍, 降低了效率.
从上面来看, 对于相同维度的聚合, 我们可以进行一次计算, 所以, DWS 和 DWT 层宽表应该以:
DWD 层进行了维度建模, 款表层只是我们为了优化数仓建的两层, 和维度建模没有任何的关系.
DWD 进行维度建模时不是以需求为驱动的, 主要以维度建模思路和步骤驱动的; 款表层是由需求指标为驱动的.
对电商系统各大主题指标分别进行分析。
对接数据仓库后续的应用, 比如 BI 报表, 用户画像, 机器学习等. 这些应用都需要数仓中的数据, 它们需要什么数据, 我们就在 ADS 层提供对应的数据.
比如, BI 报表需要展示结果, 比如一个聚合值, 那我们就把这个聚合值放到 ADS 层以供 BI 查询即可, 比如日活, 月活, 留存用户, 新增用户等.
比如, 机器学习需要大量的样例数据, 也可以放入 ADS 层;
比用户画像需要用户大量的各种信息, 也可以放在 ADS 层.
也就是说, 不同的应用, 在 ADS 层准备的数据是不同的.
建模的业务过程是 POS 零售交易, 该数据保证商业用户能够分析被销售的产品, 他们是在哪几天, 在哪个商店, 处于何种促销环境中被销售的.
最细粒度是 POS 交易的每个单品, 假设 POS 系统按照一个购物车中某种产品.
日期, 产品, 门店, 促销, 收银员, 支付方式
销售数量, 单价, 折扣, 净支付价格;
扩展折扣额;
扩展销售额 = 销量 ✖️ 单价;
扩展成本;
扩展毛利润;
销售数量, 单价, 折扣, 净支付价格;
扩展折扣额;
扩展销售额 = 销量 ✖️ 单价;
扩展成本;
扩展毛利润;
[外链图片转存中…(img-PXM3uxaq-1606195310738)]
[外链图片转存中…(img-199gR92j-1606195310738)]
[外链图片转存中…(img-p8VNuXAQ-1606195310739)]
[外链图片转存中…(img-fF1sRQXp-1606195310740)]
[外链图片转存中…(img-HZIF5K6e-1606195310740)]
[外链图片转存中…(img-wekvGH3U-1606195310741)]
Kimball - 数据仓库工具箱