数仓模型理论知识笔记

数据类型

  • 枚举类型:标称属性
  • 排序:序数属性
  • 布尔类型:二元属性
  • 普通数值:
    • 有0点:可以计算比率,所以称为比率标度属性,比如开氏温度
    • 无0点:区间标度属性,比如摄氏温度
  • 字符串

统计维度

  • 均值:普通均值、加权均值、截尾均值(舍去最大、最小的一部分之后)
  • 分位数:从小到大排序后位于每个分位的数,常用的包括中位数、4分位数、100分位数等
    • 4分位第一个点叫$Q_1$, 第三个是$Q_3$, $IQR=Q_3-Q_1$,这是四分位极差
    • 识别可疑离群点的通常规则是:挑选落在$Q_3$之上或者$Q_1$之下至少$1.5 \times IQR$位置的值
    • 五数概括:4分位点加上最小、最大值;可用盒图表示
  • 众数:出现最频繁的值
  • 中列数:最大和最小值的均值
  • 方差:个体与均值的差的平方和

可视化技术

  • 像素图
  • 散点图
  • 直方图
  • 切尔诺父脸
  • 人物线条画
  • 标签云

相似性与相异性

使用邻近性度量来量化该值。对于上文所说的集中数值类型,都有对应的公式。

对于字符串相似性,也有大量成熟算法(一般用于搜索引擎)。

建模方式

  • 星型:实际一般使用该方式,事实表+维度表
    • 事实表一般表示某些动作,维度表表示实体的属性
    • 维度表属性可能会发生改变,称为渐变维(SCD)。所以需要有一个代理主键而不能直接用维度主键。渐变维有多种处理方案:
      • SCD1: 直接用新的覆盖旧的
      • SCD2: 增加一个version字段,都存下来;另外还需要增加生效时间、过期时间字段;
      • SCD3:增加一个old_xxx字段,只最近两个版本(用的比较少)
  • 星海:多个星型共用维度表
  • 雪花:多个事实表彼此关联(速度较慢,一般不用)
  • DV: data vault,另外一种建模思路,理论模型更好,但性能较差。

维度表的维护

  • 增加列:比较简单,直接alter表结构就行。注意hive的ORC表在低版本是无法加列的;
  • 维度子集:一般是针对基础维度做物化视图,将其中某些值固定下来;
  • 角色扮演维度:多个字段共用同一张维度表,使用alias即可解决;
  • 层次维度:
    • 固定深度:可以用with rollup直接查
    • 递归:使用UDTF查询,或者用其他sql引擎;如果递归的层次不深,建议直接展开平面化
    • 多层次路径:建立多个维度表
    • 退化维度:将维度合入事实表
    • 杂项维度:避免维度表过多,可以将一些枚举项的笛卡尔积放在同一个维度表里,称为杂项维度
    • 维度合并:将多个维度合入一张表,也是利用笛卡尔积减少维度表
    • 分段维度:将数值划成多个区间,相当于加了一个枚举字段作维度

事实表的维护

事实表一般分为:

  • 事务性事实:最基本的操作性事实表;
  • 周期快照:按一定周期聚合的事实表;
  • 累计快照:基于状态变化,将整个流程记录下来。如电商发货流程;
  • 无事实的事实表:仅表明维度之间的关联关系,表本身就代表了某种事实;
  • 迟到事实:补录的数据,这个非常麻烦,所有快照表都要重新生成。如果存在这种数据,需要修改的地方比较多。

数仓分层

习惯上将离线数仓分为以下几层:

  • ODS层:源数据,基本不做任何处理
  • DW层:中间层,一般又可以分为2~3层:
    • DWD: 与ODS隔离,增加日期维度,可以用增量ODS层和前一天的DWD层进行增量计算(快照比较)
    • DWB: 清洗层,矫正数据错误、空值处理、字段合并、数据规范化等
    • DWS:聚合数据
  • ADS层:业务用的数据需求

一般对业务开放ADS和DWS层,其它层仅给数仓内部使用。

数据抽取

常用工具:

  • sqoop: dbms -> hadoop/hive
  • kettle: 类似,主要做ETL
  • dataX: 同上

全量抽取一般分为初装和后续增量抽取(CDC)。

初装比较简单,就是直接将目前数据库中所有数据全部抽过来作为ODS层。

CDC的增量方案:

  • 基于时间戳:一般数据有一个类似update_time类似的字段,表示数据更新时间,给一个阈值就可以判断出增量数据了;注意该方案无法得到物理删除(逻辑删除是可以的);
  • 基于触发器:在从库上建立触发器,实际上类似用基于变更日志的方式了;
  • 基于快照:即上文所说的ODS层与DWD层做full join对比,可能会性能较差;
  • 基于日志:比较正规的CDC方式,如MySQL的binlog;开发难度较大,不过目前使用Flink/Spark来开发也比较成熟了;