数据仓库拉链表(原理、Hive中的设计与实现)
- 首先说说拉链表的用途,拉链表是什么。
- 让我们通过一些小的使用场景以及拉链表和常用切片表的区别来了解更多关于拉链表的知识。
- 坚持针对具体的应用场景来设计并实现一个拉链表,最后用一些例子来说明我们设计的表的使用(因为现在Hive的大量使用,我们使用Hive的场景拿以下面的型号为例)。
- 分析拉链式桌子的优缺点,并对前面提到的一些内容进行进一步解释,例如拉链式桌子和自来水之间的关系。
0x01 什么是拉链表
拉链表是为表在数据仓库设计中存储数据的方式而定义的。顾名思义,所谓拉链的目的就是记录历史。记录有关对象从开始到当前状态的所有更改的信息。
我们先来看一个例子。这是一个zip表,存储了基本的用户信息和每条记录的生命周期。这个表可以让我们获取当天的最新数据以及之前的历史数据。 † 01-01
现在,我们不会详细解释此表。下面文章具体讲解如何设计、实现和使用。
拉链表使用场景
在数据库数据模型设计过程中,我们经常会遇到以下表设计:
- 有些表包含大量数据,例如用户表。大约有10亿条记录,50个字段,这样的表即使使用ORC压缩,单表的存储空间也超过100GB。如果HDFS使用双备份或者三备份的话,会比较大。
- 表中部分字段通过更新功能进行更新,如用户联系信息、产品描述信息、订单状态等。
- 您需要查看特定时间或周期的历史快照数据。例如,查看订单在历史上某个时刻的状态。
- 表记录变化的比例和频率都不是很大。例如,总共有10亿用户,每天大约有200万的新增和变化。变化的份额非常小。
这样的桌子应该如何设计呢?以下是几个选项:
- 选项 1:每天仅保留最新副本。例如,我们每天使用Sqoop将最新的全量数据提取到Hive中。
- 选项 2:每天保留零件数据的完整副本。
- 选项 3:使用带拉链的桌子。
为什么要使用拉链表
现在我们就对上面提到的三个一一进行分析。
计划1
不用说,这个计划实施起来非常简单。每天删除前一天的数据并再次提取最新的数据。
优点很明显,节省空间,对于一些常用用途也很方便。选择表时无需添加时间段。
缺点也很明显。没有历史数据。首先检查旧帐户的唯一方法是使用其他方法,例如从流程图中绘制。
方案2
每天吃足量的片是比较安全的方案,而且历史数据也有。
缺点是预留存储空间太大。如果每天都保留这张表的完整副本,则每个完整副本都会存储大量不可变数据,这是存储的巨大浪费。我还是很深刻...
当然我们也可以做一些妥协比如只保留上个月的数据?然而,需求是无耻的,我们无法完全掌控数据的生命周期。
拉链链手表
拉链链手表基本上考虑到了我们在使用中的需求。
首先,它会牺牲空间。虽然占用空间没有方案一那么小,但每天的涨幅也只能是方案二的千分之一甚至万分之一。
事实上,它可以满足选项2可以满足的需求。不仅可以获取最新数据,还可以添加过滤条件,获取历史数据。
所以我们还是需要使用拉链桌。
0x02 拉链列表的设计与实现
如何设计拉链列表
我们举个栗子,详细看一下拉链列表。
我们继续第《漫谈数据仓库之维度建模》 部分中的电子商务网站示例,现在使用用户的拉链列表进行说明。
我们先看一下Mysql关系型数据库user表的数据变化。
表格中2017年1月1日的信息为:
注册日期 | 用户号码 | 手机号码 | 手机号码 ❀10101017- 7-01- 01 | 002 | 222222 |
---|---|---|---|---|---|
2017-01-01 | 003 | 333333 | |||
2017-01-01 | 004 | 444444 |
2017-01-02 排班数据为用户 002 和 004 信息已修改,005 为新用户:
注册日期 | 用户号码 | 手机号码 | 备注 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2017-01-012.2.201721. 233333) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2017-01 -01 | 003 | 333333 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2017-01-01 | 004 | 432432 | (从 444444 更改为 432432) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2017-01-02 | 005 | 555555 | ♹(2017-01-01新增)02017)日程2017-01-03 据了解,用户004、005的信息已编辑,006为新用户:
如果该表设计为在数据仓库中保存为历史 zip 表,则会出现下表,这是最新日期(例如 2017-01 -03) 信息:
解释t_start_date代表记录的生命周期的开始时间,t_end_date =记录的生命周期的结束时间-112-- 31'表示该记录当前在有效的空间中。 当前大数据场景中基于HDFS和Hive的数据仓库架构。在当前版本的HDFS中,文件系统中的文件是不可变的,这意味着Hive表可以智能删除和添加,但不能更新。基于这个出发点,实现了拉链列表。 还是以上面的用户表为例,我们需要实现一个用户拉链表。在实施之前,我们需要确定我们有哪些可用的数据源。 并且我们需要确定拉链表的时间精度。比如拉链桌每天就只有一个空间。换句话说,如果每天有 3 个状态变化,我们只取最后一个状态。这样的日常准确度表其实可以解决大部分问题。 另外,我想补充一下如何获取每日用户更新表。根据笔者的经验,有3种方式可以获得或间接获得每日用户津贴。既然比较重要,我就详细解释一下: Ods层用户表 现在我们看一下ods层用户数据分区表的结构: Ods层user_update表我们还需要用户每日更新表,我们之前已经分析过如何获取这张表,现在我们假设它已经存在。 拉链表 现在我们创建一个拉链表: 执行sql命令 那么初始化sql就不写了。其实相当于用了ods级别的用户表一天。我们在这里写每日更新。 现在假设我们已经初始化了日期2017-01-01,那么数据需要更新到2017-01-02。我们有以下 SQL。 然后仅设置两个日期作为变量。 好了,我们分析了拉链表的原理和设计思路,并在Hive环境下实现了拉链表。让我们对拉链表进行一些小的添加。 流表存储用户变更记录。例如,在流表中,一天的数据存储了每个用户的更改记录,但在拉链表中,只有一条记录。 这是设计拉链表时需要解决的精度问题。当然我们也可以把分辨率设置低一些,一般每天就够了。 当然,zip表也面临查询性能问题。比如我们保存zip数据5年,这张表必然会比较大,查询时性能会比较低。个人认为有两个思路可以解决: 我们在本文中详细分享了与拉链列表相关的信息点,但仍然缺少一些内容。欢迎交流。 从后来的使用中积累了经验,所以我补充一下: |
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。