《大数据之路-阿里巴巴大数据实践》,作者阿里巴巴数据技术及产品部,第十章“维度设计”
《大数据之路》读书笔记:维度设计
《大数据之路》读书笔记:维度设计(续)
维度建模,维度的设计也是至关重要的,书中说“维度是维度建模的基础和灵魂”,想想在上家公司的工作,有点儿遗憾,维度这块儿没有做好。当时只是将一些维度梳理出来,但是并没有实际应用。
维度建模涉中涉及“维度表设计”和“事实表设计”,维度和事实也是常见的两个名词,维度是用来描述事实的,都说维度是描述事实的环境,环境该怎么理解呢?有点儿抽象,就是看问题的一种角度;而事实也叫度量,我们常说的指标,一般都是度量值。
常见的维度像日期维度、区域维度,维度有自己的特性,维度有属性,有层级,以日期维度为例,它可以有很多的属性,像是日期名称、月份名称、年份名称等,层级也就是常说的粒度,最细粒度一般为日,然后是月、年,所以说日期维度有3个层级,日、月、年三个层级,每个层级都有自己的属性,也有自己的唯一建。
一般来说,在SQL中,进行group by的字段都可以说是维度,其他进行聚合操作的就是度量。
维度的基本设计方法
要确定一个维度,除了基本常见的维度,比如日期、区域、组织架构等,其他的维度都会从业务中进行梳理,比如支付方式(微信支付、支付宝支付、余额支付等)、订单类型(点餐订单、自提订单、外卖订单)。
要设计一个维度,首先要确认维度的最细粒度,以商品维度为例,最细到SKU,然后会有一级品类、二级品类、三级品类、四级品类;
维度一般可以从业务系统的数据中获取,所以就会有几张表存储了商品的相关信息,我们要先确认主表,一般会把粒度最细的表当做主表,所以商品维度的话,就是sku表是主表,然后去找其他有关联关系的表;
这里我们一般会梳理出通用的属性,大部分都会是表中存在的,直接拿来用就行,还会新增一些常用的属性,可能是需要特殊处理的,尽量会让维度属性丰富些,以后就可以直接用。
属性除了编码,最好给出描述性信息
一些属性会是编码类的,一般会增加字段翻译成文字,这样用code有code,用文字有文字丰富维度属性
把常用的属性都固化到维度里,一些需要特殊处理的都一次处理好,省得每个人用的时候还要处理。开发同学经常会使用key-value或者json格式存储一些属性信息,我们就可以把常用的处理好,直接用,一些冷门的,不常用的可以不处理。
维度建模中,会有上卷或者下钻操作就是根据层级来的,像从年下钻到月,下钻到日去看数据。
规范化与反规范化
以商品维度为例,一级品类、二级品类、三级品类、四级品类,业务系统为了满足范式,一般都是拆分为单独的表,靠外键来关联,而数仓中为了方便查询,采取的是用存储换时间,会将数据打平存储到一张表中,这就是反规范化设计。
一致性维度
Conformed Dimension,一般翻译为一致性维度,一致性维度是Kimball的多维体系结构(MD)中的三个关键性概念之一,另两个是总线架构(Bus Architecture)和一致性事实(Conformed Fact)。其他俩我们后面再说,我们先看看这个一致性维度。
坦白说,一致性维度这事儿平时没咋注意,哎,外行了呀。
数据仓库的建设是逐步迭代而成的,一般开发时会按照数据集市,一个一个逐步并行或者串行开发,而每个数据集市之间某些维度可能会类似,而一致性维度就是为了保证各个数据集市之间的不同维度的一致性,说白了就是公共维度。比如说,我们公司之前有两条业务线,便利店场景和货架场景,两种场景下都有商品维度,如果我们独立开发两个数据集市,势必会在两个集市之中存有两份商品维度,而一致性维度就是保证两个维度层级、属性都是一致的,这样我们从商品维度去看便利店场景下的指标和货架场景下的指标,它们就是统一的了。
现在来说,这种公共维度不会存有两份,放在公共层,去调用就好了,传说中,数仓建设中70%的工作量都是来构建一致性维度。
交叉探查
Drill Across,也叫交叉探查,这其实是一种应用场景,在同一个维度下,查看不同业务域(数据域)的指标,就叫做交叉探查。比如:有一张表记录每天的PV、UV,还有一张表记录每天的订单数,现在从日粒度来一起来看这两个指标,这就属于交叉探查。
看英文Drill Across,回想起Drill Down,这个是下钻的意思,我估计这个drill across可能是在即席查询的时候使用的,先拖一个维度,再拖两个不同场景下的指标来一起看。
通过上面的一致性维度可以实现交叉探查,还有一种方法就是合并事实表,将同粒度同维度的指标放到同一张表中,就可以直接使用了。
感觉这个一般是前端驱动,有一种场景可能会出问题,就是说,两个指标没法挂到完全一致的维度上,比如指标A可以挂到2个维度上,而指标B只能挂到1个维度上,所以在一个维度上可以进行交叉探查,而另一个维度上则不行。
维度整合
当我们在设计维度的时候,上面说到要尽量全的覆盖维度属性,这就需要我们近可能的将相关的表进行合并,这其中除了常规的一些:
命名规范
字段类型
唯一建统一(id)
含义一致
等,还会遇到一些其他的问题,比如一对多这类问题,比如商品维度,最细粒度sku,但是每个商品可能会有多个供应商,如果将供应商信息合并到商品维度表中,就会发散掉,为了保证sku最细粒度,就会采用不合并供应商信息,而把供应商信息单独放到一张表中,或者将所有供应商信息合并为一行,可以使用key-value或者数组啥的搞一下,主要还是看用的多不多,怎么用的问题,还得结合场景来设计。垂直整合
不同来源的表,包含相同的数据集,表的粒度一致,存储的信息不一样,直接选取需要的字段就行水平整合
不同来源的表,包含不同的数据集,不同数据集间无交叉或者有交叉,然后得根据尝尽,选择是合并合适新增唯一建去合并处理。
有整合就有拆分,如果不同业务场景的同一个维度,一般不会一起使用的时候,可以拆分,或者根据使用的频率,高频使用,低频使用;较稳定变化少和变化频繁的都可以进行拆分。
历史归档
随着时间变化,数据越来越多,对于历史数据,对于那些平时不会经常使用的数据,一般会进行归档,归档有几种策略:
同前台归档策略
在数据仓库实现归档算法,定期对历史数据进行归档同前台归档策略
采用数据库变更日志的方式数据仓库自定义归档策略
这里不详述了,书中有举例子,各有利弊,比如实现算法的话比较复杂,而且可能会改归档策略,通常来说2比较靠谱