1. Предпосылки
Что такое зип-таблица? Когда хранилище данных создано, можно использовать важный метод обработки табличных данных для структурирования данных в алгоритме и сравнения зип-таблицы с хранилищем данных. Он направлен на решение требования SCD в создание хранилища данных.Так что же такое SCD?, медленно меняющееся измерение, где данные изменяются медленно относительно таблицы фактов с течением времени.
Общие методы обработки SCD следующие:
-
сохранить исходное значение
-
прямое покрытие
-
Добавить новый столбец атрибутов
-
таблица моментальных снимков
-
стол на молнии
В этой статье в основном объясняется, что такое таблица-молния для решения проблемы SCD.Его характеристики резюмируются следующим образом.При наличии следующих сценариев можно использовать таблицу-молнию.
1. Объем табличных данных велик, и использование полного масштаба потребует много места для хранения.
2. Данные таблицы будут изменены, используя добавочные таблицы, трудно иметь дело с дубликатами и изменять данные.
3. Есть потребность в возврате, и нужно знать полный объем данных на определенный момент истории
4. Данные изменены, но частота и количество не очень большие, например, изменен только один на миллион.
2. Теория обработки таблицы молнии
Во-первых, таблица Zipper представляет собой полномасштабную таблицу, а не таблицу разделов.Для достижения различных эффектов, описанных выше, в качестве промежуточного трамплина необходимо использовать промежуточную таблицу.Эта промежуточная таблица-трамплин является таблицей разделов, а данные являются инкрементными данными.Инкрементное содержимое включает в себя модификации и дополнения, т.е. частоcreate_time or update_time
Он приходится на текущий день. Для таблицы zip необходимо добавить два поля, которые не связаны с исходными данными, чтобы определить время начала данных и действительное время окончания. В примере две датыstart_date
иend_date
, существует три основных метода обработки zip-таблицы: инициализация, ежедневное обновление данных и откат данных.
2.1 Инициализация и новые данные
Его ежедневный метод прокатки выглядит следующим образом:
Часть инициализации - это время начала полной шкалы застежки-молнии, а также устанавливает самое раннее время, когда откат можно откатить.Логика ежедневного обновления показана на рисунке выше.Новые данные будут разделены на две части. частей.Если в нем есть одинаковые измененные или неизмененные данные, измените соответствующие данные соответственно.start_date
иend_date
для обновления данных.
2.1 Откат данных
Для вышеописанной логики обновления рассмотрим, как откатить данные, то есть вернуться к определенному моменту в истории, для зиппер-таблицы это полная шкала, поэтому откат только один. Стратегия отката может быть сгенерирована на основе момента времени отката и данных.start_date
иend_date
, как откатиться, давайте посмотрим на следующую принципиальную схему:
существует
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');
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
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 обновляется, здесь повторяться не будет.