1. 为了解决大数据数据仓库中,不能更新的问题, 我们就采用拉链表进行弥补了这样的问题。拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。

2.采用的架构

在这里插入图片描述

3.实现过程

3.1 比如数据有一张表test_student

以下是2021年1月3号的数据,

id name create_time update_time
1 hdfs 2021-02-03 09:45:16 2021-02-03 09:45:22
2 hive 2021-02-03 09:45:30 2021-02-03 09:45:34

3.2 将1月3号的数据通过sqoop 导入到hdfs 在加载到hive 中

将数据导入hdfs中

sqoop import \
--connect jdbc:mysql://slave03.com:10051/test_db \
--username root \
--password Mysql@20211231.20221 \
--target-dir hdfs://master01.com:8020/origin_data/db_hive/db/resource/test_db/2021-02-03 \
--delete-target-dir \
--query "SELECT id, NAME, create_time, update_time FROM test_student WHERE ( DATE_FORMAT(create_time, '%Y-%m-%d') = '2021-02-03' OR DATE_FORMAT(update_time, '%Y-%m-%d') = '2021-02-03' ) and  \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec lzop \
--null-string '\\N' \
--null-non-string '\\N'

3.3数据加载到hive

原始表:

CREATE external TABLE `ods_student` (
  `id` bigint COMMENT 'id',
  `name` string COMMENT '创建者',
  `create_time` TIMESTAMP COMMENT '创建时间',
  `update_time` TIMESTAMP COMMENT '更新时间'
)  COMMENT '原始表'
PARTITIONED BY (`dt` string)
row format delimited fields terminated by '\t'
STORED AS
  INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
  OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
location '/warehouse/tablespace/external/hive/db_wudl/ods_student/';

3.4加载数据

load data inpath '/origin_data/db_hive/db/resource/test_db/2021-02-03' OVERWRITE into table db_wudl.ods_student partition(dt='2021-02-03')

查询如下:
在这里插入图片描述

3.4 初始化拉链表

create external table ods_student_his(
    `id` bigint COMMENT '用户id',
    `name` string COMMENT '姓名', 
    `create_time` TIMESTAMP COMMENT '创建时间',
    `update_time` TIMESTAMP COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '用户拉链表'
stored as parquet
location '/warehouse/tablespace/external/hive/db_wudl/ods_student_his/'
tblproperties ("parquet.compression"="lzo");

3.5 数据初始化拉链表

SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
insert overwrite table ods_student_his SELECT id, NAME, create_time, update_time, '2021-02-03', '9999-99-99' FROM ods_student oi WHERE oi.dt = '2021-02-03';

如果1月4号 在增加在增加一条数据并且在修改数据,如下:

1月三号的数据

id name create_time update_time
1 hdfs 2021-02-03 09:45:16 2021-02-03 09:45:22
2 hive 2021-02-03 09:45:30 2021-02-03 09:45:34

1月四号的数据
在这里插入图片描述
这样就将修改的数据增加了一条flink 数据修改了之前的hive 数据

3.4再次同步2月4号的数据

sqoop import \
--connect jdbc:mysql://slave03.com:10051/test_db \
--username root \
--password Mysql@20211231.20221 \
--target-dir hdfs://master01.com:8020/origin_data/db_hive/db/resource/test_db/2021-02-04 \
--delete-target-dir \
--query "SELECT id, NAME, create_time, update_time FROM test_student WHERE ( DATE_FORMAT(create_time, '%Y-%m-%d') = '2021-02-04' OR DATE_FORMAT(update_time, '%Y-%m-%d') = '2021-02-04' ) and  \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec lzop \
--null-string '\\N' \
--null-non-string '\\N'

3.5 进行数据加载

load data inpath '/origin_data/db_hive/db/resource/test_db/2021-02-04' OVERWRITE into table db_wudl.ods_student partition(dt='2021-02-04')

3.6查询原始表

在这里插入图片描述

拉链临时表的创建

create external table ods_student_his_tmp(
    `id` bigint COMMENT '用户id',
    `name` string COMMENT '姓名', 
    `create_time` TIMESTAMP COMMENT '创建时间',
    `update_time` TIMESTAMP COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'
stored as parquet
location '/warehouse/tablespace/external/hive/db_wudl/ods_student_his_tmp/'
tblproperties ("parquet.compression"="lzo");

3.7 原始表和拉链临时表进行关联

INSERT overwrite TABLE ods_student_his_tmp SELECT
	*
FROM
	(
		SELECT
			id,
			NAME,
			create_time,
			update_time,
			'2021-02-04' start_date,
			'9999-99-99' end_date
		FROM
			ods_student
		WHERE
			dt = '2021-02-04'
		UNION ALL
			SELECT
				uh.id,
				uh. NAME,
				uh.create_time,
				uh.update_time,
				uh.start_date,

			IF (
				ui.id IS NOT NULL
				AND uh.end_date = '9999-99-99',
				date_add(ui.dt ,- 1),
				uh.end_date
			) end_date
			FROM
				ods_student_his uh
			LEFT JOIN (
				SELECT
					*
				FROM
					ods_student
				WHERE
					dt = '2021-02-04'
			) ui ON uh.id = ui.id
	) his
ORDER BY
	his.id,
	start_date;

拉链临时表数据
在这里插入图片描述

覆盖

insert overwrite table ods_student_his  select * from ods_student_his_tmp;

最终显示:
在这里插入图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐