Sakila 租赁业务数据集成案例
案例介绍
本文所介绍的 ETL 解决方案基于一个虚拟的 DVD 出租连锁店 Sakila,通过一个非常简单的星型模型对其进行分析,这个星型模型来自 MySQL 免费的 sakila 数据库。在这个示例中,系统定期从源数据库 sakila 抽取增量数据。然后转换成符合星型模型的数据,最后把数据加载到目标数据库的租赁业务星型模型中。剩下的内容简单地讨论了源数据库和目标数据库的模型,这样可以帮助读者理解 ETL 方案的工作方式和原理。
sakila数据库介绍
为了对 sakila 数据库模型有一个全面的了解,读者可以参考相关的官方文档。实际上,这个模型本身非常简单且易于理解,参考相关的业务流程可以非常容易地理解其本质。
DVD光盘业务租赁流程
sakila 数据库的主要目的在于支撑 DVD 租赁商店的业务流程,下面列举了一些业务流程活动中的关键点来帮助理解sakila 数据库是如何支撑的:
- 每个商店维护自己的租赁影片清单,当客户取走或归还 DVD 光盘时会有一个专门的店员对这个清单进行维护。
- 影片描写的内容同样在维护信息范围之列,如分类(动作、冒险、喜剧等)、演员、等级、特殊分类(例如被删除的情节和预告片)。这些信息可能被打印在 DVD 包装的标签上。
- 必须在商店注册成为会员才可以租赁光盘。
- 客户可以在任何一家商店租赁一张或多张光盘,同时,商店希望客户在每张光盘对应的的租赁期内归还之前租赁的光盘。
- 顾客可以在任意时间对任何租赁的光盘付费。
sakila数据库主题分类
下图为 sakila 数据库的关系图,读者可以按照自己的分类方式对这些表进行分类。

为了更快地使读者了解数据库模型的主从表关系,我们建议将其分为四个主题,具体分类如下:
- 电影类:包含 film 表和包含影片附加信息的表,如 category、actor 和 language。
- 商店类:包括 store 表和相关联的 staff 表、inventory 表。
- 客户类:以 customer 表为主线,包含与顾客有关联的 rental 表和 payment 表。
- 区域表:包括 country、city 和 address 表,这些表为顾客、商店和员工提供标准化的字典信息。
总体设计规范
了解总体设计规范可以加深对 sakila 数据库设计的理解,具体内容如下:
- sakila 数据库表采用单一对象名称命名。
- 每张表都有自增主键列,列名采用“表名_id”的规则命名,如表 file 的自增主键列为【film_id】。
- 外键约束引用主键,且名字与主键列的相同。例如,表 store 的【address_id】列引用表 address 的【address_id】列。
- 每张表都有一列叫做【last_update】,这是一个 TIMESTAMP 类型的字段,用来记录增加或更新数据时的时间。
安装sakila示例数据库
在安装 sakila 示例数据库之前。用户需要下载并安装 MySQL 关系型数据库的最新版本,最低版本不能低于 5.0。安装完 MySQL 数据库后,下载本文提供的 sakila 数据库建库脚本,按照如下步骤进行安装:
1、sakila 建库脚本下载链接: 数据库结构文件:sakila-schema.sql
数据文件:sakila-data.sql 2、使用 mysql 的 source 命令运行上述两个脚本,假设脚本位置在 D:\mysql\ 中,则命令如下:
Mysql \> Source D:\mysql\sakila-schema.sql
Mysql \> Source D:\mysql\sakila-data.sql
租赁业务 星型模型
租赁业务的星型模型来源于 sakila 示例数据库,它是租赁业务里可能的几个维度模型之一。租赁星型模型的结构如下图所示:

上图展示了一个典型的维度模型,它包含一个叫做 fact_rental 的事实表,事实表与多个维度表关联。这种维度建模方式非常适用于联机事务处理(OLAP)。它同样也是一个经典的星型模式,因为几乎所有的维度都是单一的,维度表之间没有关联,维度表只和事实表有关。
租赁事实表
事实表的名称是 fact_rental,包含了一些数值类型的能体现出业绩的业务度量值(【count_returns】、【count_rentals】、【rental_duration】)。此外,事实表还包含一些列,用来作为指向维度表的键。当用户访问某个度量值时,维度表中的数据将提供该度量值对应的业务维度。
在 sakila 模型中,fact_rental 表与 sakila 模式下的原始 rental 表直接对应:rental表中的一行生成【fact_rental】表中的一行。
维度表
之前我们提到过,租赁业务星型模型的每一个维度都是一个单独的维度表。星型模型维度表的命名全部遵守了dim_<dimension-name> 的规则,其中 <dimension-name> 用来描述维度的内容。
根据之前 sakila 数据库模型的分类,星型模型图中建议将维度表按照相关概念分为四组(加上一组事实表“how much?”,一共五组)。
- 人员(who):这组包括 dim_customer 表和 dim_staff 表,分别代表租赁业务中的客户和员工。这是属于类型2的缓慢变化维度:维度表里用%_version_number、%_valid_from和%_valid_through列来跟踪同一客户或员工的历史记录。
- 时间(when):这组中的维度表主要用来记录所有光盘租赁或归还的时间点,其中,维度表 dim_date 实际是日历,它是所谓的角色扮演维度,用来同时标记租赁日期和归还日期。而 dim_time 维度表则用来记录当天租赁的时间。
- 地点(where):维度表 dim_store 用来记录 DVD 光盘是从哪个商店租赁的,和 dim_staff、dim_customer 一样,dim_store 也是缓慢增长维,也有一组列用来记录同一个商店的不同历史版本。
- 事件(what):这组包括 dim_actor 和 dim_film 两个维度表,它们是租赁业务的主题。只有 dim_film 表和fact_rental 表直接关联,因为电影才是租赁和归还的实际对象。但是,一部电影由众多演员构成,这些演员在某种意义上也是租赁的对象。这就是所谓的桥接表 dim_film_actor_bridge 的由来,该表联系了演员和电影。另外,该表保存了一个权重因子,用来评估一个演员对影片的贡献值。通过原始指标值乘以权重因子就可以从演员的角度分析租赁收入,而把原来的指标值看成附加值。例如,我们就可以回答这样的问题:上个月 Robert De Niro 或 Al Pacino 的电影获得了多少租金收益?
在租赁业务的星型模型中,从源数据库 sakila 模型中派生出来的每个维度(除了表 dim_date 和 dim_time )都对应着 sakila 数据模型中的某个表。例如,维度表 dim_store 对应着业务系统中的 store 表,维度表 dim_actor 对应着actor 表。
键和变更数据捕获
除了表 dim_date 和 dim_time,每个维度表都使用自增列作为代理主键,表 dim_date 和 dim_time 的主键将在稍后介绍,它们的主键叫做智能键。这两个表的智能键分别来源于部分时间和日期,它可以在 ETL 过程中直接发挥作用,也用来对事实表做分区。
维度表的键值被用来关联表 fact_rental 和维度表。所有维度表的主键列都以 <维度名称>_key 来命名,<维度名称>就是维度表的表名除了 dim_前缀 之外的剩余部分。
在讨论 sakila 数据库模式的设计规范时,曾提到源模式中的每个表里都有【last_update】字段,该字段保存了一个时间戳 TIMESTAMP,用来存储每一行的最后修改(或添加)时间。在接下来的内容中可以看到这个字段对于变更数据捕获非常有用,变更数据捕获对数据持续增长的场景非常有用。虽然变更数据捕获的方法有很多种,我们这里使用的是一种最直接的方法:每个维度表都有【last_update】字段,这个字段保存了原始 sakila 模式中对应表的【last_update】字段的值。这样可以在维度表上执行一个查询,获得最后加载日期/时间,并用这个日期/时间来识别和抽取所有源数据库里对应表的最新变更的数据行。
除了代理主键,每个维度表也包含一列用来存储来自 sakila 数据模型的主键值,例如,星型模型中的表 dim_film 有一列【film_id】用来保存表 film 中的【film_id】,当你读完后面的内容,就会知道这些列的重要性,这 些列用来判断变更的数据是增加的还是更新的数据。
安装租赁业务的星型模型
租赁星型模型的安装步骤同源 sakila示例数据库的相同,将租赁星型模型的脚本文件在 MySQL 命令行中使用 SOURCE 命令执行。安装步骤如下:
1、下载租赁星型模型的脚本文件
数据文件: sakila_dwh_data.sql
表结构文件: sakila_dwh_schema.sql
2、使用 mysql 的 source 命令运行上述两个脚本,假设脚本位置在 D:\mysql\ 中,则命令如下:
Mysql > Source D:\mysql\sakila_dwh_schema.sql
Mysql > Source D:\mysql\sakila_dwh_data.sql
在接下来的 ETL 解决方案中,将把 sakila 源数据库中的数据加载到星型模型中,因此我们在本小节中只导入星型模型的表结构即可,不用加载数据。如果使用加载数据的 SQL 脚本加载了数据,后面的 ETL 流程也能执行:只不过不能再加载变化的数据。
ETL示例解决方案
前面我们已经对数据库模型进行了讨论。接下来将介绍如何使用ETL解决方案把数据从sakila示例数据库加载到租赁星型模型。
生成静态维度
维度表 dim_date 和 dim_time 属于静态维度类型:通过数据集进行初始化并且不需要定期从sakila示例数据库进行加载(虽然可能在未来需要表 dim_date 生成更多的日期数据)。