빅 데이터 개발 --- 데이터웨어 하우스 지퍼 테이블 개요 및 반복 또는 롤백 방법

1. 배경

지퍼 테이블의 정의 데이터웨어 하우스가 구축되면 데이터웨어 하우스의 지퍼 테이블과 유사한 알고리즘으로 데이터를 구조화하는 데 중요한 테이블 데이터 처리 방법을 사용하여 데이터웨어 하우스 구축시 SCD 요구 사항을 해결할 수 있습니다. 데이터웨어 하우스, 그래서 SCD는 천천히 변화하는 차원입니까? 시간이 지남에 따라 데이터는 팩트 테이블에 비해 느리게 변경됩니다.

SCD의 일반적인 처리 방법은 다음과 같습니다.

  • 원래 가치 유지

  • 직접 적용

  • 새 속성 열 추가

  • 스냅 샷 테이블

  • 지퍼 테이블

이 기사에서는 주로 SCD의 문제점을 다루는 지퍼 테이블에 대해 설명하며, 그 특성을 다음과 같이 요약하여 다음과 같은 시나리오가있을 때 지퍼 테이블을 사용할 수 있습니다.

1. 미터 데이터의 양이 많고 전체 미터는 많은 저장 공간을 차지합니다.

2. 테이블 데이터가 수정됩니다. 증분 테이블을 사용하면 중복 및 수정 된 데이터 처리가 어렵습니다.

3. 역 추적이 필요하며, 기록의 특정 시점에서 데이터의 전체 양을 알아야합니다.

4. 데이터가 수정되었지만 빈도와 양이 그리 크지 않습니다. 예를 들어 백만 분의 1 만 수정되었습니다.

2. 지퍼 테이블 처리 이론

우선 지퍼 테이블은 파티션 테이블이 아닌 실물 크기의 테이블입니다. 위에서 설명한 다양한 효과를 얻기 위해서는 중간 테이블을 중간 스프링 보드로 사용해야합니다. 중간 스프링 보드 테이블은 파티션 테이블입니다. 증분 데이터입니다. 증분 콘텐츠에는 수정 사항이 포함되며 일반적으로 create_time or update_time현재 날짜에 추가 됩니다. 지퍼 테이블의 경우 데이터 시작 시간과 유효 기한을 식별하기 위해 원래 데이터와 관련이없는 두 개의 필드를 추가해야합니다. 예를 들어,이 두 날짜는 start_dateend_date입니다. 지퍼 테이블에는 초기화, 매일 데이터 업데이트, 데이터 롤백의 세 가지 주요 처리 방법이 있습니다.

2.1 초기화 및 새 데이터

일일 압연 방법은 다음과 같습니다.

파일

초기화 부분은 지퍼 풀 스케일의 시작 시간이며 롤백이 가능한 가장 빠른 시간을 의미합니다. 일일 업데이트 로직은 위 그림과 같습니다. 새 데이터는 두 개로 나뉩니다. 부분, 하나는 매일 추가되는 데이터이고, 그날의 파티션은 데이터가 변경 될 때 변동이 있거나 동일하지 않으며, 각각 해당 수정 start_dateend_date업데이트 데이터를 달성 할 수 있습니다.

2.1 데이터 롤백

위의 업데이트 로직에서는 데이터를 롤백하는 방법, 즉 히스토리의 특정 지점으로 돌아가는 방법을 고려해 보겠습니다. 지퍼 테이블의 경우 전체 스케일이므로 롤백이 하나뿐입니다. 롤백 전략은 롤백 시간 및 데이터 생성을 가리킬 수 start_date있으며 end_date, 특히 롤백 방법은 다음 다이어그램을 참조하십시오.

파일에서 end_date < rollback_date데이터 처리를 위해 예약되는 end_date ≥ rollback_date ≥ start_date세트 end_date에 대한 9999-12-31데이터의 일반적인 무결성을 유지하기 위해, 결과를 롤백 데이터가 다시 새 임시 테이블 파스너 압연 할 수있다.

3. 지퍼 테이블 처리 케이스

일반적으로 사용되는 데이터웨어 하우스의 계층 적 DIM의 경우, 즉 차원 계층이 지퍼 테이블의 일반적인 시나리오입니다. 다음은 지퍼 테이블을 추가하고 롤백하는 방법을 보여주는 예입니다.

지퍼 테이블은 핵심 트랜잭션 분석에서 DIM 계층 판매자 차원 테이블을 구현하고 지퍼 테이블의 롤백을 실현하는 데 사용됩니다.

3.1 테이블 생성 및 데이터 가져 오기

판매자 차원 테이블의 구조는 다음과 같습니다.

--创建商家信息表(增量表 分区表)
drop table if exists ods.ods_trade_shops;
create table ods.ods_trade_shops(
  `shopid` int COMMENT '商铺ID',
  `userid` int COMMENT '商铺负责人', 
  `areaid` int COMMENT '区域ID',
  `shopname` string COMMENT '商铺名称',
  `shoplevel` int COMMENT '商铺等级',
  `status` int COMMENT '商铺状态',
  `createtime` string COMMENT '创建日期',
  `modifytime` string COMMENT  '修改日期'
) COMMENT '商家信息表'
PARTITIONED BY (`dt` string)
row format delimited fields terminated by ',';

-- 创建商家信息维表
drop table if exists dim.dim_trade_shops;
create table dim.dim_trade_shops(
  `shopid` int COMMENT '商铺ID',
  `userid` int COMMENT '商铺负责人', 
  `areaid` int COMMENT '区域ID',
  `shopname` string COMMENT '商铺名称',
  `shoplevel` int COMMENT '商铺等级',
  `status` int COMMENT '商铺状态',
  `createtime` string COMMENT '创建日期',
  `modifytime` string COMMENT  '修改日期',
  `startdate` string  COMMENT '生效起始日期',
  `enddate` string  COMMENT '失效结束日期'
) COMMENT '商家信息表';

다음 테스트 데이터를 가져옵니다.

/root/data/shop-2020-11-20.dat
100050,1,100225,WSxxx营超市,1,1,2020-06-28,2020-11-20 13:22:22
100052,2,100236,新鲜xxx旗舰店,1,1,2020-06-28,2020-11-20 13:22:22
100053,3,100011,华为xxx旗舰店,1,1,2020-06-28,2020-11-20 13:22:22
100054,4,100159,小米xxx旗舰店,1,1,2020-06-28,2020-11-20 13:22:22
100055,5,100211,苹果xxx旗舰店,1,1,2020-06-28,2020-11-20 13:22:22


/root/data/shop-2020-11-21.dat
100057,7,100311,三只xxx鼠零食,1,1,2020-06-28,2020-11-21 13:22:22
100058,8,100329,良子xxx铺美食,1,1,2020-06-28,2020-11-21 13:22:22
100054,4,100159,小米xxx旗舰店,2,1,2020-06-28,2020-11-21 13:22:22
100055,5,100211,苹果xxx旗舰店,2,1,2020-06-28,2020-11-21 13:22:22


/root/data/shop-2020-11-22.dat
100059,9,100225,乐居xxx日用品,1,1,2020-06-28,2020-11-22 13:22:22
100060,10,100211,同仁xxx大健康,1,1,2020-06-28,2020-11-22 13:22:22
100052,2,100236,新鲜xxx旗舰店,1,2,2020-06-28,2020-11-22 13:22:22

load data local inpath '/root/data/shop-2020-11-20.dat' overwrite into table ods.ods_trade_shops partition(dt='2020-11-20');
load data local inpath '/root/data/shop-2020-11-21.dat' overwrite  into table ods.ods_trade_shops partition(dt='2020-11-21');
load data local inpath '/root/data/shop-2020-11-22.dat' overwrite  into table ods.ods_trade_shops partition(dt='2020-11-22');

3.2 지퍼 테이블 초기화

첫날의 데이터가 모두 과거 데이터라고 가정

INSERT OVERWRITE TABLE dim.dim_trade_shops
SELECT shopid,
       userid,
       areaid,
       shopname,
       shoplevel,
       status,
       createtime,
       modifytime,
       CASE
           WHEN modifytime IS NOT NULL THEN substr(modifytime, 0, 10)
           ELSE substr(createtime, 0, 10)
       END AS startdate,
       '9999-12-31' AS enddate
FROM ods.ods_trade_shops
WHERE dt ='2020-11-20';

3.3 지퍼 테이블 업데이트

증분 테이블의 경우 일반 논리는 create_time또는 modifytime일 파티션으로 차단 dt, modifytime보다 크거나 같음 create_time, 여기에서 처음 2 개를 가져옵니다.

INSERT OVERWRITE TABLE dim.dim_trade_shops
SELECT shopid,
       userid,
       areaid,
       shopname,
       shoplevel,
       status,
       createtime,
       modifytime,
       CASE
           WHEN modifytime IS NOT NULL THEN substr(modifytime, 0, 10)
           ELSE substr(createtime, 0, 10)
       END AS startdate,
       '9999-12-31' AS enddate
FROM ods.ods_trade_shops
WHERE dt = '2020-11-21'
UNION ALL
SELECT b.shopid,
       b.userid,
       b.areaid,
       b.shopname,
       b.shoplevel,
       b.status,
       b.createtime,
       b.modifytime,
       b.startdate,
       CASE
           WHEN a.shopid IS NOT NULL
                AND b.enddate ='9999-12-31' THEN date_add('2020-11-21', -1)
           ELSE b.enddate
       END AS enddate
FROM
  (SELECT *
   FROM ods.ods_trade_shops
   WHERE dt='2020-11-21') a
RIGHT JOIN dim.dim_trade_shops b ON a.shopid = b.shopid;

지퍼 테이블을로드하는 스크립트는 다음과 같습니다.

dim_load_shops.sh

#!/bin/bash

source /etc/profile
if [ -n "$1" ]
then
  do_date=$1
else
  do_date=`date -d "-1 day" +%F`
fi

sql="
INSERT OVERWRITE TABLE dim.dim_trade_shops
SELECT shopid,
       userid,
       areaid,
       shopname,
       shoplevel,
       status,
       createtime,
       modifytime,
       CASE
           WHEN modifytime IS NOT NULL THEN substr(modifytime, 0, 10)
           ELSE substr(createtime, 0, 10)
       END AS startdate,
       '9999-12-31' AS enddate
FROM ods.ods_trade_shops
WHERE dt = '$do_date'
UNION ALL
SELECT b.shopid,
       b.userid,
       b.areaid,
       b.shopname,
       b.shoplevel,
       b.status,
       b.createtime,
       b.modifytime,
       b.startdate,
       CASE
           WHEN a.shopid IS NOT NULL
                AND b.enddate ='9999-12-31' THEN date_add('$do_date', -1)
           ELSE b.enddate
       END AS enddate
FROM
  (SELECT *
   FROM ods.ods_trade_shops
   WHERE dt='$do_date') a
RIGHT JOIN dim.dim_trade_shops b ON a.shopid = b.shopid;
"

hive -e "$sql"

이 스크립트를 실행 2020-12-22하여 데이터 를로드 할 수 있습니다 .sh dim_load_shops.sh 2020-12-22

3.4 지퍼 테이블을 특정 시점으로 롤백

먼저 tmp.shops_tmp롤백 된 데이터를 넣을 임시 테이블 만듭니다.

DROP TABLE IF EXISTS tmp.shops_tmp;
CREATE TABLE IF NOT EXISTS tmp.tmp_shops AS
SELECT shopid,
       userid,
       areaid,
       shopname,
       shoplevel,
       status,
       createtime,
       modifytime,
       startdate,
       enddate
FROM dim.dim_trade_shops
WHERE enddate < '2020-11-21'
UNION ALL
SELECT shopid,
       userid,
       areaid,
       shopname,
       shoplevel,
       status,
       createtime,
       modifytime,
       startdate,
       '9999-12-31' AS enddate
FROM dim.dim_trade_shops
WHERE startdate <= '2020-11-21'
  AND enddate >= '2020-11-21';


INSERT OVERWRITE TABLE dim.dim_trade_shops
SELECT *
FROM tmp.tmp_shops;

롤백 스크립트는 SQL이 업데이트되는 한 여기에서 반복되지 않는 업데이트 스크립트와 유사합니다. Wu Xie, Xiao San Ye, 백그라운드에서 작은 신인, 빅 데이터 및 인공 지능. 더 많은 것을 주목하십시오파일

추천

출처blog.csdn.net/hu_lichao/article/details/111147473