Hive
Hive主要实现了两个功能:
- 提供了一个存储和管理元数据的HiveMetastore,以库和表的形式管理HDFS中的元数据。
- 实现了一套将SQL转换为MapReduce程序的执行引擎。
Hive执行原理
- 所有的命令和查询都会进入Driver(驱动模块),通过该模块对输入进行解析编译,对需求的计算进行优化,然后按照指定的步骤执行(通常是启动多个MapReduce任务(Job)来执行),
- 当需要启动MapReduce任务(Job)时,Hive本身是不会生成Java MapReduce程序的。Hive通过一个表示“Job执行任务”的XML文件驱动执行内置的、原生的Mapper模块和Reducer模块。
- 换句话说,这些通用的模块函数类似于微型的语言翻译程序,而这个驱动计算的“语言”是以XML形式编码的。
Hive是一门声明式语言,用户会提交声明式的查询,而Hive会将其转换成MapReduce Job。
可以通过Java调试器来调试Hive,hive --help --debug
数据仓库
概念
- 维度表:对实时的描述信息,比如用户表(id, name, birthday),地址表(id, name) 。
- 事实表:代表那些业务表,比如订单表,支付表等。事实是那些可度量的值,比如金额,个数等。用户行为数据表其实也相当于事实(每个记录表示次数为1)。
- 事务型事实表:一旦生成记录后就不回去更改的表,比如支付记录。更新方式:增量更新(因为之前的记录不会发生改变)。
- 周期型快照事实表:表中的记录会不断改变,比如购物车表。
- 累计型快照事实表:主要用来跟踪业务事实的变化,比如订单表中(order_id, user_id, 下单时间, 打包时间, 发货时间, 签收时间, amount)。
表的同步策略
- 全量表:存储完整的数据。一般是以日期为分区,做每日全量(将表中的数据全部导入到当日分区表),当天的分区即是最新的数据,前一天的数据即为历史数据,适用于表的数据量不大,并且每天有新数据的插入和旧数据的更改的情况。
- 增量表:存储新增加的数据。一般是以日期为分区,做每日增量(将表中今日新增的数据导入当日分区表),当前的分区即是今日新增的数据,取全表数据即为所有的数据,适用于数据量大,每天只会有新数据插入的情况。
- 新增即变化表:存储新增加和变化的数据。将表中新增和变化的数据同步到今日的分区中,一般是做拉链表。
- 特殊表:只需要存储一次。一般用于不会更改的维度信息,比如民族、性别等。
维度建模
- 把表分为两种,事实表和维度表
- 主要有三种:
- 星型模型:一个事实表,多个维度表,并且所有的维度表只与事实表相关联。
- 雪花模型:一个事实表,多个维度表,但是维度表之间可以有关联,比较接近数据库的范式,但不会完全遵守。
- 星座模型:多个事实表,多个维度表,事实表之间可以共享维度表。
- 选择业务过程:比如下单业务
- 声明粒度:一般以最小粒度,即每条记录的含义,订单事实表中一行数据表示的是一个订单记录。
- 确定维度:维度的作用就是描述事实,确定维度就是从某个角度来看事实,比如需要统计哪一天的订单最多、哪个地区的订单最多、哪个用户的订单最多,此时用到的就是日期维度、地区纬度、用户维度。维度一般会以字段的形式存在表中。
- 确定事实:确定好度量值,比如订单表(订单编号,时间,用户,地区,订单金额):时间、用户、地区是维度,订单金额是度量。
数据仓库的分层
- ODS层:不需要维度建模,直接存储原样的数据即可。行为日志数据用只有一个字段的分区表存储;业务数据用相同结构的分区表存储(同步策略如上)。
- DWD层:需要进行维度建模,参照维度建模的部分。行为日志数据需要在此层进行分类,分成多个分区表存储;业务数据则需要在此层进行维度建模,从而减少高层的Join,并且在此层建立一些维度表(将本来符合范式的多个表合成一个维度表)和事实表(事实表中包含维度字段,即看待数据的角度,到时候直接group by即可得出对应维度的信息)。该层是基于业务,即行为日志数据的格式和MySQL中的业务数据格式。
- DWS层:也称为宽表层,该表的主题实际上就是对应的维度。每条记录相当于有两个维度了,即时间和用户,或者时间和商品,并且每个用户或商品在此表中就一条记录,求出的数据也是当天的某个用户的购买次数、登录次数,当天某个商品被购买的次数。并且宽表应该预留一些字段,下次有新需求时可能就不需要更改表结构。
- DWT层:和DWS层类似,不过存放的是累计值,并且DWS层是分区表(以日期为分区),DWT是普通的外部表。比如DWS层只存储某个用户当天的订单数、购买金额、购买的商品等;但是DWT层存储的是某个用户首次登陆时间、最近登陆时间、总订单数、总购买金额和最近30天的登录次数、订单数等。并且DWT中的表应该是全量表。
- ADS层:不涉及到建模,根据分析主题来看。
如何制作拉链表(用于同步策略为新增及变化的表):
- 业务表中应该有
create_date
和update_date
字段,并且设置好触发器 - ods层导入业务表中的新增及变化的数据,即
create_date
或者update_date
字段等于今天的记录,并且该表是分区表。 - 拉链表是否有数据,如果没有数据则需要初始化(使用
sqoop
将业务表中所有数据放入拉链表中,设置create_date
为业务表中的数据,end_date
为9999-99-99
) - 读取ods层表的数据,设置
create_date
为今天、end_date
为9999-99-99
为new
,读取拉链表中的旧数据为old
,将old
和new
做左连接,连接条件为new.id = old.id
,并且设置if(new.id is not null and old.end_date='9999-99-99', date_add(old.dt, -1), old.end_date) end_date
,此连接会查出旧表中的数据 - 将new表和左连接查询出来的表做
union all
操作,得到的表插入拉链表中,即完成了拉链表的制作过程。