赞
踩
作为一名数据分析师,想要进行数据分析,首先要学会准确地获取数据,数据来源于数据库表,想要获取数据就需要知道库表的存储位置、存储形式等信息。一般来说,公司对于表的命名都有统一规范,比如:(1)表明数据存储于哪些库,是数据接入层还是数据明细层?是数据聚合层还是数据应用层?这些层分别对应于哪些库,命名是什么。(2)包含业务线、业务主题、表名、更新周期是什么。
维度表: 业务过程的业务实体 ,如:商品,用户,订单。
维度表中常见的column字段包含:
- 代理键(自增列,可以充当主键)
- 自然键(唯一区分,商品id,订单id)
- 维度属性(商品的大小,颜色等)
事实表: 业务内特定事件的数据(大量的行) ,如:商品的销售记录。
事实表的常见分类包括: 全量表 、 增量表 、 流水表 、拉链表 。
接下来,我们将重点介绍什么是全量表、增量表、快照表和拉链表。
表的命名规范:
\quad
表中常见的i
、s
、a
,分别代表增量表
、快照表
、全量表
。
全量表: 记录更新周期内的全量数据
,无论数据是否有变化都需要记录;
全量表的典型特征:
每次往全量表里面写数据都会覆盖之前的数据,所以全量表不能记录历史的数据情况
,只有截止到当前最新的、全量的数据。全量表的典型范例:
举个例子,2021年3月13号的全量表如图,当天有两位用户,其支付状态都是待支付。
2021年3月14号,uid为1的用户支付了,且当天新增了一位已支付的uid为3的用户,那么2021年3月14号的全量表就变成了下图,13号uid为1的用户待支付状态更新为已支付。
增量表: 记录更新周期内的新增数据
,即在原表中数据的基础上新增本周期内产生的新数据,没变化的数据不会被记录;
增量表的典型特征:
增量表的典型范例:
增量表,就是记录每天新增数据的表。比如:从24号到25号新增了哪些数据,改变了哪些数据,这些都会存储在增量表在25号的分区里面。
增量表和快照表中【分区时间】分别代表什么?
\quad
- 快照表中时间分区 t t t 日,实际代表第 t + 1 t+1 t+1日,例如:快照表中的25号分区和24号分区实际时间分别对应26号和25号),它俩的数据相减就是实际时间25号到26号有变化的、增加的数据,也就相当于增量表里面25号分区的数据。
- 增量表中时间分区 t t t 日,实际代表第 t t t 日。
\quad流量和存量的定义与区别:
\quad
- 流量: 是指在一定时间内的增量,流量一般设计成增量表(日报-常用、月报);
- 存量: 是指在一定时间内的总量,存量一般设计成总量表;
- 流量和存量的区别:
流量是增量,存量是总量
;
快照表: 就是截至过去某个时间点的所有数据,主要对过去某个时间点的数据状态进行记录,即:快照表主要存储的是历史状态的表
,每个快照的数据单独存储在一个分区中。
快照表的适用场景:
为解决全量表无法查询历史数据的情况,引入了快照表。快照表是有时间分区的,每个分区里的数据都是分区时间对应的前一天的所有全量数据,比如:当前数据表有3个分区,24号、25号、26号。其中,24号分区里面的数据就是从历史到23号的所有数据,25号分区里面的数据就是从历史到24号的所有数据,以此类推。
快照表的典型特征:
按照时间分区进行数据存储;
快照表的优缺点:
快照表的典型范例:
快照表用来存储截止过去某个时间点的所有数据,比如:一些用户特征的表、标签表、订单状态表等多存储于快照表中,其实快照表
也有所区分,本质是一段时间内数据的记录
,主要还是看底层报表开发人员的逻辑。
从历史到此分区前一天的所有数据
,如:12号分区中的数据是从历史到11号的所有数据,13号分区中的数据是从历史到12号的所有数据,其他的以此类推。从历史到此分区的所有数据
,如:12号分区中的数据是从历史到12号的所有数据,13号分区中的数据是从历史到13号的所有数据,其他的以此类推。日常工作中我们也会经常用到快照表,以前不懂的时候就取好几个分区,导致取了大量且重复的数据,实际上快照表最近的一个分区就存储了从历史到当前分区的所有数据,我们只需要取一个分区就可满足取数需求。
流水表: 对于表的每一个修改都会记录
,可以用于反映实际记录的变更。
流水表的典型特征:
业务相关情况
;拉链表
可以根据拉链粒度存储数据,也就是只存储特定维度的数据变化记录;而流水表
存储的是每一个修改记录( 拉链表与流水表的区别)。鉴于全量表、快照表的缺点,为了在保留所有状态的情况下,有效节省存储空间,引入了拉链表。
拉链表: 是一种维护历史状态,以及最新状态数据的一种表,记录数据从开始一直到当前状态所有变化的信息
。
拉链表的典型特征:
账户及客户的情况
;表结构基本一样
。拉链表
存储的是在快照表
的基础上去除了重复状态的数据,也就是说一些不变的信息在快照表中每个分区都会存储一份,可能造成存储浪费,而使用拉链表在更新频率和比例不是很大的情况下会十分节省存储。( 拉链表与快照表的区别)。拉链表的适用场景:
当数据量较大,表中某些字段有变化,但变化频率不是很高,而业务需求又需要统计这种变化状态,如果每天存储一份全量数据,不仅浪费存储空间,且不便于业务统计;这时,拉链表的作用就体现出来了,既节省空间,又满足需求。
在数据仓库的数据模型设计过程中,经常会遇到这样的需求:
此时,如果对张表每天都保留一份全量,那么每次全量中会保存很多不变的信息,这对存储是极大的浪费;拉链表,既能满足反应数据的历史状态,又能最大程度地节省存储空间。
拉链表的优缺点:
拉链表的典型范例:
举个简单例子,比如有一张订单表,6月20号有3条记录:
订单创建日期 | 订单编号 | 订单状态 |
---|---|---|
2012-06-20 | 001 | 创建订单 |
2012-06-20 | 002 | 创建订单 |
2012-06-20 | 003 | 支付完成 |
到6月21日,表中有5条记录:
订单创建日期 | 订单编号 | 订单状态 |
---|---|---|
2012-06-20 | 001 | 支付完成(从【创建订单】update到【支付完成】) |
2012-06-20 | 002 | 创建订单 |
2012-06-20 | 003 | 支付完成 |
2012-06-21 | 004 | 创建订单 |
2012-06-21 | 005 | 创建订单 |
到6月22日,表中有6条记录:
订单创建日期 | 订单编号 | 订单状态 |
---|---|---|
2012-06-20 | 001 | 支付完成(从【创建订单】update到【支付完成】) |
2012-06-20 | 002 | 创建订单 |
2012-06-20 | 003 | 已发货(从【支付完成】update到【已发货】) |
2012-06-21 | 004 | 创建订单 |
2012-06-21 | 005 | 支付完成(从【创建订单】update到【支付完成】) |
2012-06-22 | 006 | 创建订单 |
数据仓库中对该表的保留方法:
如果在数据仓库中设计成 历史拉链表 来保存数据,则会有下面这样一张表:
一般在数仓中通过增加dw_begin_date
,dw_end_date
两个字段来表征 历史拉链表 。
订单创建日期 | 订单编号 | 订单状态 | dw_begin_date | dw_end_date |
---|---|---|---|---|
2012-06-20 | 001 | 创建订单 | 2012-06-20 | 2012-06-20 |
2012-06-20 | 001 | 支付完成 | 2012-06-21 | 9999-12-31 |
2012-06-20 | 002 | 创建订单 | 2012-06-20 | 9999-12-31 |
2012-06-20 | 003 | 支付完成 | 2012-06-20 | 2012-06-21 |
2012-06-20 | 003 | 已发货 | 2012-06-22 | 9999-12-31 |
2012-06-21 | 004 | 创建订单 | 2012-06-21 | 9999-12-31 |
2012-06-21 | 005 | 创建订单 | 2012-06-21 | 2012-06-21 |
2012-06-21 | 005 | 支付完成 | 2012-06-22 | 9999-12-31 |
2012-06-22 | 006 | 创建订单 | 2012-06-22 | 9999-12-31 |
表中的字段及使用说明:
该条记录的生命周期开始时间
;该条记录的生命周期结束时间
;该条记录目前处于有效状态
;
- 如果查询当前所有有效的记录,则
select * from order_his where dw_end_date = ‘9999-12-31′
- 如果查询2012-06-21的历史快照,则
select * from order_his where dw_begin_date <= ‘2012-06-21′ and end_date >= ‘2012-06-21’
,这条语句会查询到以下记录;- 通过dw_end_date过滤2020-06-02之前的旧数据;
- 通过dw_begin_date过滤2020-06-02之后的新数据。
订单创建日期 | 订单编号 | 订单状态 | dw_begin_date | dw_end_date |
---|---|---|---|---|
2012-06-20 | 001 | 支付完成 | 2012-06-21 | 9999-12-31 |
2012-06-20 | 002 | 创建订单 | 2012-06-20 | 9999-12-31 |
2012-06-20 | 003 | 支付完成 | 2012-06-20 | 2012-06-21 |
2012-06-21 | 004 | 创建订单 | 2012-06-21 | 9999-12-31 |
2012-06-21 | 005 | 创建订单 | 2012-06-21 | 2012-06-21 |
和源表在6月21日的记录完全一致:
订单创建日期 | 订单编号 | 订单状态 |
---|---|---|
2012-06-20 | 001 | 支付完成(从【创建订单】update到【支付完成】) |
2012-06-20 | 002 | 创建订单 |
2012-06-20 | 003 | 支付完成 |
2012-06-21 | 004 | 创建订单 |
2012-06-21 | 005 | 创建订单 |
可以看出,这样的历史拉链表,既能满足对历史数据的需求,又能很大程度的节省存储资源;
参考链接:
2、MySQL实现拉链表操作——hive中拉链表
5、拉链表
6、拉链表(二)
拉链表的使用方法:
全量表
记录数据的历史状态;(2)增量表
记录数据的增量信息);按照每天存放的数据以及是否按天分区,增量表,全量表和快照表
全量表 | 增量表 | 快照表 |
---|---|---|
包含从开始到前一天的全量数据 | 包含前一天的增量数据 | 包含前一天的全量数据 |
分区 | 不分区(ymd为当前日期) | 按照每一天进行分区 |
总体而言,在数据量不是很大的情况下是可以优先考虑使用全量表进行数据存储,该方法简单,但会很耗资源。
一般,建议使用增量表进行存储,毕竟目前大多数公司的数据量都很大,且数据量都在不断增长。
当遇到历史状态需要保存的时候就需要使用快照表和拉链表了,比如:上面提到的一些标签、用户特征、订单状态等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。