Data Warehouse_Zipper Table_Zipper Table Implementation Ideas

Este artículo, explica principalmente

 1. ¿Qué es una mesa con cremallera y un ejemplo de visualización de cremallera?

 2. Cómo construir una mesa con cremallera bajo diferentes tablas originales

 

Primero introduce qué es la mesa con cremallera

 

1. ¿Qué es una mesa con cremallera y un ejemplo de visualización de cremallera?

¿Qué es un reloj con cremallera?

     Cuando los datos de dimensión cambian, los datos antiguos se invalidan y los datos modificados se insertan en la tabla de dimensiones como un nuevo registro y entran en vigencia. Esto puede registrar el historial de cambios de datos con una cierta granularidad.

 

 

Ejemplo de mesa con cremallera

      Por favor vea mi otro artículo

 https://blog.csdn.net/u010003835/article/details/104420723

 

 

 

 2. Cómo construir una mesa con cremallera bajo diferentes tablas originales

 

1. El primer caso, la tabla estandarizada

    ¿Qué es una tabla estándar? El estándar significa que la tabla original contiene create_time, update_time  

 

Asumiendo la tabla original a la tabla del almacén de datos, el método de recolección diaria

Luego construimos la tabla e insertamos datos de prueba


use data_warehouse_test;

CREATE TABLE IF NOT EXISTS user_zipper_org (
	user_id BIGINT COMMENT '用户id'
	,user_name STRING COMMENT '用户姓名'
	,create_time DATE COMMENT '创建时间'
	,update_time DATE COMMENT '修改时间'
) 
PARTITIONED BY(
	pt STRING COMMENT '数据分区'
)
STORED AS ORC
;


ALTER TABLE user_zipper_org DROP IF EXISTS PARTITION (pt = '20200320');
ALTER TABLE user_zipper_org DROP IF EXISTS PARTITION (pt = '20200321');


INSERT INTO TABLE user_zipper_org PARTITION (pt = '20200320')
VALUES 
(1, 'szh', '2020-01-01', '2020-01-01')
,(2, 'yuqin', '2020-01-01', '2020-01-01')
,(3, 'heping', '2020-01-01', '2020-01-01')
,(4, 'quxingma', '2020-01-01', '2020-01-01')
,(5, 'zhouzhou', '2020-01-01', '2020-01-01')
;

INSERT INTO TABLE user_zipper_org PARTITION (pt = '20200321')
VALUES 
(1, 'szh2', '2020-01-01', '2020-03-21')
,(2, 'yuqin', '2020-01-01', '2020-01-01')
,(3, 'heping3', '2020-01-01', '2020-03-21')
,(4, 'quxingma', '2020-01-01', '2020-01-01')
,(5, 'zhouzhou', '2020-01-01', '2020-01-01')
,(6, 'newuser', '2020-03-21', '2020-03-21')
;

 

Cree la tabla final de la cremallera, para garantizar la seguridad de los datos, nuestra tabla final de la cremallera es una tabla de partición

En primer lugar, dado que la tabla de la cremallera se construyó a partir de 20200320, todos los datos de la tabla original son equivalentes a los datos válidos actualmente. Construimos los datos finales de la tabla de la cremallera de 20200320 en base a estos datos.

En segundo lugar, necesitamos construir tablas temporales a partir de los datos particionados en la tabla final 20200320.

El SQL de los dos pasos anteriores es el siguiente

use data_warehouse_test;

CREATE TABLE IF NOT EXISTS user_zipper_final
(
	user_id BIGINT COMMENT '用户id'
	,user_name STRING COMMENT '用户姓名'
	,create_time DATE COMMENT '创建时间'
	,update_time DATE COMMENT '修改时间'
	,start_date DATE COMMENT '生效时间'
	,end_date DATE COMMENT '失效时间'
)
PARTITIONED BY(
	pt STRING COMMENT '数据分区'
);


INSERT OVERWRITE TABLE user_zipper_final PARTITION (pt = '20200320')
SELECT 
	org.user_id
	,org.user_name
	,org.create_time
	,org.update_time
	,'2020-03-20' AS start_date
	,'9999-12-31' AS end_date
FROM user_zipper_org AS org
WHERE pt = '20200320'
;


DROP TABLE IF EXISTS tmp_user_zipper_mid;
CREATE TABLE tmp_user_zipper_mid AS
SELECT 
	org.user_id
	,org.user_name
	,org.create_time
	,org.update_time
	,org.start_date
	,org.end_date
FROM user_zipper_final AS org
WHERE pt = '20200320'
;

 

 

Los pasos clave se basan en los datos que cambiaron en 20200321 (nuevos y modificados)

El nuevo create_time es 2020-03-21

El tiempo de actualización modificado es 2020-03-21

Y la cantidad total de datos de la tabla de cremallera de 20200320, para construir los datos de la tabla de cremallera de 20200321 (aquí primero almacenamos como una tabla temporal, es decir, una tabla intermedia)

 

Primero, podemos obtener datos nuevos y modificados de esta manera

2020-03-21 发生变动的数据

SELECT 
	org.user_id
	,org.user_name
	,org.create_time
	,org.update_time
	,'2020-03-20' AS start_date
	,'9999-12-31' AS end_date
FROM user_zipper_org AS org
WHERE pt = '20200321'
	AND (
		(
			create_time = '2020-03-21'
		)
		OR
		(
			update_time = '2020-03-21'
		)
	)
;

 

Los datos de la tabla de cremalleras completa de 20200321 se pueden construir de la siguiente manera

use data_warehouse_test;

DROP TABLE IF EXISTS tmp_user_zipper_mid;

CREATE TABLE tmp_user_zipper_mid AS
SELECT *
FROM
(
SELECT 
	final.user_id
	,final.user_name
	,final.create_time
	,final.update_time
	,final.start_date
	,CAST (
		(
			CASE 
				WHEN 
					(
						new_data.user_id IS NOT NULL 
						AND
						final.end_date >= '2020-03-21' 
					)
					THEN '2020-03-20'
				ELSE final.end_date
			END 
		)	
		AS DATE
	)
	AS end_date
FROM 
	user_zipper_final AS final
LEFT JOIN (
	SELECT 
	org.user_id
	,org.user_name
	,org.create_time
	,org.update_time
	FROM user_zipper_org AS org
	WHERE pt = '20200321'
		AND (
			(
				create_time = '2020-03-21'
			)
			OR
			(
				update_time = '2020-03-21'
			)
		)
) AS new_data
ON  new_data.user_id = final.user_id
WHERE final.pt = '20200320'

UNION ALL

SELECT 
	new_data.user_id
	,new_data.user_name
	,new_data.create_time
	,new_data.update_time
	,CAST( '2020-03-21' AS DATE ) AS start_date
	,CAST ('9999-12-31' AS DATE ) AS end_date
FROM (
	SELECT 
	org.user_id
	,org.user_name
	,org.create_time
	,org.update_time
	FROM user_zipper_org AS org
	WHERE pt = '20200321'
		AND (
			(
				create_time = '2020-03-21'
			)
			OR
			(
				update_time = '2020-03-21'
			)
		)
) AS new_data
) AS tmp
;

 

 

Finalmente, insertamos los resultados de la tabla temporal en la nueva partición de la tabla de la cremallera.

Luego, verificamos los datos (

1. Obtenga los últimos datos de partición de la tabla de cremalleras

2. Obtenga los datos de 2020-03-20 a través de la tabla de cremalleras

3. Obtenga los datos de 2020-03-21 a través de la tabla de cremalleras


use data_warehouse_test;

INSERT OVERWRITE TABLE user_zipper_final PARTITION (pt = '20200321')
SELECT 
	* 
FROM tmp_user_zipper_mid
;


SELECT *
FROM user_zipper_final
WHERE pt = '20200321'
;


SELECT * 
FROM user_zipper_final 
WHERE pt = '20200321' 
	AND start_date <= '2020-03-20' 
	AND end_date >= '2020-03-20'
;


SELECT * 
FROM user_zipper_final 
WHERE pt = '20200321' 
	AND start_date <= '2020-03-21' 
	AND end_date >= '2020-03-21'
;

 

 

 

2. El segundo caso, la tabla original no estándar

     Lo que es una tabla original no estándar es que no hay create_time o update_time en la tabla original. O aún más, los dos no existen. En tales circunstancias, ¿cómo debemos construir la tabla de la cremallera?

 

Analizamos cuidadosamente este problema, ¿cómo resolverlo?

En primer lugar, podemos ver que a través de un solo create_time o update_time, no podemos distinguir los datos modificados.

Por lo tanto, nuestra idea es construir una columna para identificar los datos modificados.

¡Elegimos la forma de tomar valores md5 para todas las columnas! ! ! !

 

Supongamos que nuestra tabla original tiene las siguientes columnas,

user_id, user_name, create_time

则 MD5 (CONCAT (user_id, user_name, create_time))  

Suponiendo que ya tenemos una tabla de cremallera inicial, la dificultad radica en cómo obtener los datos modificados (nuevos y modificados)

El SQL para obtener datos modificados es el siguiente:

SELECT
	ta.*
FROM 
(
	SELECT 
		user_id
		,user_name
		,create_time
		,MD5(CONCAT(user_id,user_name,create_time)) AS user_flag
	FROM user_zipper_org
	WHERE pt = '20200321'
) AS ta
LEFT JOIN (
	SELECT 
		user_id
		,user_flag
	FROM user_zipper_final
	WHERE pt = '20200320'
		AND start_date <= '2020-03-20'
		AND end_date >= '2020-03-20'
) AS tb
ON ta.user_id = tb.user_id
AND ta.user_flag != tb.user_flag
;

 

 

 

 

 

 

519 artículos originales publicados · elogiados 1146 · 2,83 millones de visitas

Supongo que te gusta

Origin blog.csdn.net/u010003835/article/details/104849019
Recomendado
Clasificación