Разработка больших данных — обзор зип-таблицы хранилища данных и способы итерации или отката

Большие данные

1. Предпосылки

Что такое зип-таблица? Когда хранилище данных создано, можно использовать важный метод обработки табличных данных для структурирования данных в алгоритме и сравнения зип-таблицы с хранилищем данных. Он направлен на решение требования SCD в создание хранилища данных.Так что же такое SCD?, медленно меняющееся измерение, где данные изменяются медленно относительно таблицы фактов с течением времени.

Общие методы обработки SCD следующие:

  • сохранить исходное значение

  • прямое покрытие

  • Добавить новый столбец атрибутов

  • таблица моментальных снимков

  • стол на молнии

В этой статье в основном объясняется, что такое таблица-молния для решения проблемы SCD.Его характеристики резюмируются следующим образом.При наличии следующих сценариев можно использовать таблицу-молнию.

1. Объем табличных данных велик, и использование полного масштаба потребует много места для хранения.

2. Данные таблицы будут изменены, используя добавочные таблицы, трудно иметь дело с дубликатами и изменять данные.

3. Есть потребность в возврате, и нужно знать полный объем данных на определенный момент истории

4. Данные изменены, но частота и количество не очень большие, например, изменен только один на миллион.

2. Теория обработки таблицы молнии

Во-первых, таблица Zipper представляет собой полномасштабную таблицу, а не таблицу разделов.Для достижения различных эффектов, описанных выше, в качестве промежуточного трамплина необходимо использовать промежуточную таблицу.Эта промежуточная таблица-трамплин является таблицей разделов, а данные являются инкрементными данными.Инкрементное содержимое включает в себя модификации и дополнения, т.е. частоcreate_time or update_timeОн приходится на текущий день. Для таблицы zip необходимо добавить два поля, которые не связаны с исходными данными, чтобы определить время начала данных и действительное время окончания. В примере две датыstart_date иend_date, существует три основных метода обработки zip-таблицы: инициализация, ежедневное обновление данных и откат данных.

2.1 Инициализация и новые данные

Его ежедневный метод прокатки выглядит следующим образом:

file

Часть инициализации - это время начала полной шкалы застежки-молнии, а также устанавливает самое раннее время, когда откат можно откатить.Логика ежедневного обновления показана на рисунке выше.Новые данные будут разделены на две части. частей.Если в нем есть одинаковые измененные или неизмененные данные, измените соответствующие данные соответственно.start_date иend_dateдля обновления данных.

2.1 Откат данных

Для вышеописанной логики обновления рассмотрим, как откатить данные, то есть вернуться к определенному моменту в истории, для зиппер-таблицы это полная шкала, поэтому откат только один. Стратегия отката может быть сгенерирована на основе момента времени отката и данных.start_date иend_date, как откатиться, давайте посмотрим на следующую принципиальную схему:

fileсуществуетend_date < rollback_dateданные, которые необходимо сохранить для обработкиend_date ≥ rollback_date ≥ start_dateнастраиватьend_dateза9999-12-31, В результате отката, как правило, для сохранения целостности данных, откатные данные могут быть помещены в новую временную таблицу zip.

3. Случай обработки стола с застежкой-молнией

Для обычно используемой иерархической DIM хранилищ данных, то есть уровня измерения, является обычным сценарием для zip-таблиц.Вот пример, чтобы увидеть, как добавлять и откатывать zipper-таблицы.

Используйте таблицу zip для реализации таблицы измерения продавца слоя DIM в анализе основной транзакции и реализации отката таблицы zip.

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');

file

3.2 Инициализация таблицы Zipper

Предположим, что данные за первый день используются как все исторические данные.

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 , вот возьми первые два

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;

Сценарий для загрузки zip-таблицы выглядит следующим образом:

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

file

3.4 Откат zip-таблицы на определенный момент времени

Сначала создайте временную таблицу,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 обновляется, здесь повторяться не будет.