MySQL Sakila样本数据库
Mysql(免安装版)安装、配置与卸载
MySQL:由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题
缓慢变化维类型
1、类型一
对源系统的更新,也会直接更新目标维度表。维度表总是保存当前最新的状态,如果发生变化就直接覆盖。可以通过kettle的“插入/更新”
步骤来实现。
2、 类型二
对源系统的更新,会往目标维度表里插入一行数据,通过不同的时间戳来维护同一条维度数据的多个版本。在任何一个给定的时间点,都可以找到一行对应的维度数据,可以按照时间追踪到维度的变化。
3、类型三
对源系统的更新,会在目标维度表里增加列,在目标维度表同一行新增的列里保存新的数据。kettle里没有一个专用的步骤来支持,但是可以写一个作业并使用“表里面的列是否存在”
步骤来判断是否要更改表结构,然后使用“SQL脚本”
步骤,执行相应的DDL语句增加一个新列。
以上缓慢变化维类型的处理方式,在实际开发中使用最多的是类型二,类型三很少使用,需重点掌握类型一和类型二。
以租赁业务为主题搭建如下星型模型
执行sakila_dwh_schema.sql文件,创建sakila_dwh数据仓库的库和表。
源数据库
目标数据库
kettle
注意:kettle连接MySQL 8.0以上版本时,需要调整连接配置,请参考 关于 kettle 连接 mysql 的一些问题。
ETL数据流向:源(sakila)—> 目标(sakila_dwh)
类型 | 数据抽取方式 | 说明 |
---|---|---|
维度表 | 全量抽取/增量抽取 | 不删除任何数据 |
事实表 | 增量抽取 | 需要删除数据 |
时间维度是一个静态维度类型,无需考虑维度属性的变化。
[load_dim_date.ktr](etl)
# 生成连续日期数据
SELECT
date_format(t.date_value, '%Y%m%d') AS date_key,
t.date_value,
date_format(t.date_value, '%c/%e/%y') AS date_short,
date_format(t.date_value, '%b %e, %Y') AS date_medium,
date_format(t.date_value, '%M %e, %Y') AS date_long,
date_format(t.date_value, '%W, %M %e, %Y') AS date_full,
dayofyear(t.date_value) AS day_in_year,
dayofmonth(t.date_value) AS day_in_month,
CASE WHEN dayofmonth(t.date_value) = 1 THEN 1
ELSE 0
END AS is_first_day_in_month,
CASE WHEN dayofmonth(ADDDATE(t.date_value, 1)) = 1 THEN 1
ELSE 0
END AS is_last_day_in_month,
date_format(t.date_value, '%a') AS day_abbreviation,
date_format(t.date_value, '%W') AS day_name,
week(t.date_value, 3) AS week_in_year,
(DAY(t.date_value)+WEEKDAY(t.date_value-INTERVAL DAY(t.date_value) DAY)) DIV 7 + 1 AS week_in_month,
CASE WHEN weekday(t.date_value) = 0 THEN 1
ELSE 0
END AS is_first_day_in_week,
CASE WHEN weekday(ADDDATE(t.date_value, 1)) = 0 THEN 1
ELSE 0
END AS is_last_day_in_week,
month(t.date_value) AS month_number,
date_format(t.date_value, '%b') AS month_abbreviation,
date_format(t.date_value, '%M') AS month_name,
date_format(t.date_value, '%y') AS year2,
date_format(t.date_value, '%Y') AS year4,
concat('Q', quarter(t.date_value)) AS quarter_name,
quarter(t.date_value) AS quarter_number,
concat(year(t.date_value), 'Q', quarter(t.date_value)) AS year_quarter,
date_format(t.date_value, '%Y-%m') AS year_month_number,
date_format(t.date_value, '%b %Y') AS year_month_abbreviation
FROM(
SELECT
date_format(date_add('2000-01-01', interval r.rental_id - 1 day), '%Y-%m-%d') AS date_value
FROM
rental r
) t
WHERE t.date_value <= '2020-12-31'
ORDER BY t.date_value
员工维度是一个动态维度类型,需要考虑维度属性的变化,此处采用类型二的处理方式来设计数据加载过程。
不存在物理删除的情况,所以无需考虑维度中已被删除数据的处理(staff表中的“active”字段,“1”表示数据有效,“0”表示数据无效,即被删除)。
作业/转换 | 功能 | 文件位置 |
---|---|---|
load_dim_staff.kjb | 负责调度后面的三个转换 | [load_dim_staff.kjb](etl) |
first_load.ktr | 首次加载dim_staff数据 | [first_load.ktr](etl\dim_staff_job) |
load_new_add.ktr | 加载新增加的数据和更新旧行数据 | [load_new_add.ktr](etl\dim_staff_job) |
load_new_update.ktr | 加载新行数据 | [load_new_update.ktr](etl\dim_staff_job) |
客户维度同样属于缓慢变化维度。
作业/转换 | 功能 | 文件位置 |
---|---|---|
load_dim_customer.kjb | 负责调度后面的三个转换 | [load_dim_custpomer.kjb](etl) |
first_load.ktr | 首次加载dim_staff数据 | [first_load.ktr](etl\dim_customer_job) |
load_new_add.ktr | 加载新增加的数据和更新旧行数据 | [load_new_add.ktr](etl\dim_customer_job) |
load_new_update.ktr | 加载新行数据 | [load_new_update.ktr](etl\dim_customer_job) |
观察actor表,并不存在缓慢变化维度属性,所以采用类型一处理即可。
[load_dim_actor.ktr](etl)
[load_dim_film.ktr](etl)
商店维度同样属于缓慢变化维度。
作业/转换 | 功能 | 文件位置 |
---|---|---|
load_dim_store.kjb | 负责调度后面的三个转换 | [load_dim_store.kjb](etl) |
first_load.ktr | 首次加载dim_store数据 | [first_load.ktr](etl\dim_store_job) |
load_new_add.ktr | 加载新增加的数据和更新旧行数据 | [load_new_add.ktr](etl\dim_store_job) |
load_new_update.ktr | 加载新行数据 | [load_new_update.ktr](etl\dim_store_job) |
观察rental表发现,该表中没有逻辑删除标识,前端如果删除掉一笔租赁交易,rental中相应的记录会被直接删除。对此,数仓的响应机制是需要删除掉在源系统中已不存在的记录,以确保事实数据的准确性。可根据业务数据修改的周期性设置数仓删除记录的时间范围。
事实表中的数据积累速度快且数据体量大,故采用增量加载方式抽取数据。
作业/转换 | 功能 | 文件位置 |
---|---|---|
load_fact_rental.kjb | 负责调度后面的三个转换 | [load_fact_rental.kjb](etl) |
first_load.ktr | 首次加载fact_rental数据 | [first_load.ktr](etl\fact_rental_job) |
delete_data.ktr | 删除数据 | [delete_data.ktr](etl\fact_rental_job) |
load_new.ktr | 加载最新数据 | [load_new.ktr](etl\fact_rental_job) |