大数据Hive拉链表的设计与实现

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 大数据Hive拉链表的设计与实现

1 数据同步问题

1.1 数据同步的场景

Hive在实际工作中主要用于构建离线数据仓库,定期的从各种数据源中同步采集数据到Hive中,经过分层转换提供数据应用。例如,每天需要从MySQL中同步最新的订单信息、用户信息、店铺信息等到数据仓库中,进行订单分析、用户分析。

例如:MySQL中有一张用户表:tb_user,每个用户注册完成以后,就会在用户表中新增该用户的信息,记录该用户的id、手机号码、用户名、性别、地址等信息。

9eccabfb25914f18a2694e9a974f41f1.png

每天都会有用户注册,产生新的用户信息,我们每天都需要将MySQL中的用户数据同步到Hive数据仓库中,在做用户分析时,需要对用户的信息做统计分析,例如统计新增用户的个数、总用户个数、用户性别分布、地区分布、运营商分布等指标。

1.2 数据同步的问题

在实现数据仓库数据同步的过程中,我们必须保证Hive中的数据与MySQL中的数据是一致的,这样才能确保我们最终分析出来的结果是准确的,没有问题的,但是在实现同步的过程中,这里会面临一个问题:如果MySQL中的数据发生了修改,Hive中如何存储被修改的数据?

例如以下情况

➢ 2021-01-01:MySQL中有10条用户信息

➢ 2021-01-02:Hive进行数据分析,将MySQL中的数据同步

⚫ 2021-01-02:MySQL中新增2条用户注册数据,并且有1条用户数据发生更新

◼ 新增两条用户数据011和012

◼ 008的addr发生了更新,从gz更新为sh

⚫ 2021-01-03:Hive需要对2号的数据进行同步更新处理

⚫ 问题:新增的数据会直接加载7.1.3 解决方案

➢ 方案一:在Hive中用新的addr覆盖008的老的addr,直接更新

到Hive表中,但是更新的数据如何存储在Hive表中?

➢ 优点:实现最简单,使用起来最方便

➢ 缺点:没有历史状态,008的地址是1月2号在sh,但是1月2号之前是在gz的,如果要查询008的1月2号之前的addr就无法查询,也不能使用sh代替

➢ 方案二:每次数据改变,根据日期构建一份全量的快照表,每天一张表

➢ 2021-01-02:Hive中有一张表tb_user_2021-01-02

➢ 2021-01-03:Hive中有一张表tb_user_2021-01-03

➢ 优点:记录了所有数据在不同时间的状态

➢ 缺点:冗余存储了很多没有发生变化的数据,导致存储的数据量过大

➢ 方案三:构建拉链表,通过时间标记发生变化的数据的每种状态的时间周期

2 拉链表的设计

2.1 功能与应用场景

拉链表专门用于解决在数据仓库中数据发生变化如何实现数据存储的问题,如果直接覆盖历史状态,会导致无法查询历史状态,如果将所有数据单独切片存储,会导致存储大量非更新数据的问题。拉链表的设计是将更新的数据进行状态记录,没有发生更新的数据不进行状态存储,用于存储所有数据在不同时间上的所有状态,通过时间进行标记每个状态的生命周期,查询时,根据需求可以获取指定时间范围状态的数据,默认用9999-12-31等最大值来表示最新状态。

2.2 实现过程

整体实现过程一般分为三步,第一步先增量采集所有新增数据【增加的数据和发生变化的数据】放入一张增量表。第二步创建一张临时表,用于将老的拉链表与增量表进行合并。第三步,最后将临时表的数据覆盖写入拉链表中。例如:

当前MySQL中的数据:

当前Hive数据仓库中拉链表的数据:

⚫ step1:增量采集变化数据,放入增量表中

⚫ step2:构建临时表,将Hive中的拉链表与临时表的数据进行合并

⚫ step3:将临时表的数据覆盖写入拉链表中

3 拉链表的实现

3.1 数据准备

➢ 创建dw层拉链表

--创建数据库
create database db_zipper;
use db_zipper;
--创建拉链表
create table dw_zipper(
  userid string,
  phone string,
  nick string,
  gender int,
  addr string,
  starttime string,
  endtime string
) row format delimited fields terminated by '\t';
➢ 构建模拟数据:vim /export/data/zipper.txt
```sql
001 186xxxx1234 laoda 0 sh  2021-01-01  9999-12-31
002 186xxxx1235 laoer 1 bj  2021-01-01  9999-12-31
003 186xxxx1236 laosan  0 sz  2021-01-01  9999-12-31
004 186xxxx1237 laosi 1 gz  2021-01-01  9999-12-31
005 186xxxx1238 laowu 0 sh  2021-01-01  9999-12-31
006 186xxxx1239 laoliu  1 bj  2021-01-01  9999-12-31
007 186xxxx1240 laoqi 0 sz  2021-01-01  9999-12-31
008 186xxxx1241 laoba 1 gz  2021-01-01  9999-12-31
009 186xxxx1242 laojiu  0 sh  2021-01-01  9999-12-31
010 186xxxx1243 laoshi  1 bj  2021-01-01  9999-12-31

➢ 加载拉链表数据

–加载模拟数据

load data local inpath ‘/export/data/zipper.txt’ into table dw_zipper;

➢ 查询数据

select userid,nick,addr,starttime,endtime from dw_zipper;

3.2 增量采集

➢ 创建ods层增量表

create table ods_zipper_update(
  userid string,
  phone string,
  nick string,
  gender int,
  addr string,
  starttime string,
  endtime string
) row format delimited fields terminated by '\t';

➢ 创建模拟数据:vim /export/data/update.txt

008 186xxxx1241 laoba 1 sh 2021-01-02 9999-12-31

011 186xxxx1244 laoshi 1 jx 2021-01-02 9999-12-31

012 186xxxx1245 laoshi 0 zj 2021-01-02 9999-12-31


➢ 加载更新数据

load data local inpath ‘/export/data/update.txt’ into table ods_zipper_update;


➢ 查询数据select userid,nick,addr,starttime,endtime from ods_zipper_update;

3.3 合并数据

➢ 创建临时表
create table tmp_zipper(
  userid string,
  phone string,
  nick string,
  gender int,
  addr string,
  starttime string,
  endtime string
) row format delimited fields terminated by '\t';

➢ 合并拉链表与增量表

insert overwrite table tmp_zipper
select
  userid,
  phone,
  nick,
  gender,
  addr,
  starttime,
  endtime
from ods_zipper_update
union all
--查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTime
select
  a.userid,
  a.phone,
  a.nick,
  a.gender,
  a.addr,
  a.starttime,
  --如果这条数据没有更新或者这条数据不是要更改的数据,就保留原来的值,否则就改为新数据的开始时间-1
  if(b.userid is null or a.endtime < '9999-12-31', a.endtime , date_sub(b.starttime,1)) as endtime
from dw_zipper a  left join ods_zipper_update b
on a.userid = b.userid ;

3.4 生成最新拉链表

➢ 覆盖拉链表

insert overwrite table dw_zipper
select * from tmp_zipper;


相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
SQL 分布式计算 大数据
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
本文深入介绍 Hive 与大数据融合构建强大数据仓库的实战指南。涵盖 Hive 简介、优势、安装配置、数据处理、性能优化及安全管理等内容,并通过互联网广告和物流行业案例分析,展示其实际应用。具有专业性、可操作性和参考价值。
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
417 0
|
SQL 分布式计算 大数据
大数据处理平台Hive详解
【7月更文挑战第15天】Hive作为基于Hadoop的数据仓库工具,在大数据处理和分析领域发挥着重要作用。通过提供类SQL的查询语言,Hive降低了数据处理的门槛,使得具有SQL背景的开发者可以轻松地处理大规模数据。然而,Hive也存在查询延迟高、表达能力有限等缺点,需要在实际应用中根据具体场景和需求进行选择和优化。
1323 6
|
SQL 分布式计算 大数据
MaxCompute产品使用合集之启用hive兼容的时候,某个字段是null,是否会把这个字段当成空白连起来
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
SQL 数据采集 数据可视化
基于Hive的招聘网站的大数据分析系统
基于Hive的招聘网站的大数据分析系统
474 2
|
SQL 关系型数据库 MySQL
基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)
基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)
830 0
|
SQL 存储 Java
Hive 拉链表详解及实例
拉链表是一种数据仓库技术,用于处理持续增长且存在时间范围内的重复数据,以节省空间。它在Hive中通过列式存储ORC实现,适用于大规模数据场景,尤其当数据在有限时间内有多种状态变化。配置涉及事务管理和表合并选项。示例中展示了如何从原始订单表创建拉链表,通过聚合操作和动态分区减少数据冗余。增量数据可通过追加到原始表然后更新拉链表来处理。提供的Java代码用于生成模拟的订单增量数据,以演示拉链表的工作流程。
1137 3
|
分布式计算 DataWorks 调度
MaxCompute产品使用合集之如何将数据迁移到CDH Hive
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
394 0
|
SQL 分布式计算 大数据
[AIGC 大数据基础]hive浅谈
[AIGC 大数据基础]hive浅谈
332 0
|
9月前
|
机器学习/深度学习 传感器 分布式计算
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
599 14