了解使用 Oracle Warehouse Builder 11g 开发数据仓库的基础知识。
2011 年 4 月发布
上学时,我们知道,尽管大多数数学题都有清晰明了的公式,但我们仍须用未知数 x 来列方程,有时还要用 x、y 甚至更多未知数来列出方程组,以便求解。类似地,在决策支持系统中,我们须根据清晰表述的业务问题来设计一组数据对象,例如维度和多维数据集,以便解答这些问题。
本文着重介绍如何构建一个维度环境以解答业务问题。具体来说,本文将介绍如何将某些分析问题转化为获得答案所需的一组数据对象,使用 Oracle Warehouse Builder 作为开发工具。最好的学习方式是通过示例,因此本文将指导您构建一个简单的数据仓库。
一般数据仓库主要针对销售,旨在利用基于时间、产品或客户条件从销售多维数据集中检索的结果,帮助用户找到有关业务状况的问题的答案。而本文中的示例不同于一般情况。在这里,您将观察一个示例,了解如何利用基于地理、资源和时间条件从一个流量多维数据集中检索的信息,分析特定网站的相关传出流量。
假设您拥有一个网站,其资源托管在多台服务器上,每台服务器存储流量统计信息的方式都各不相同。从关系数据库到平面文件,它们使用的存储类型多种多样。您需要整合所有这些服务器上的流量统计信息,以便分析用户活动,包括所访问的资源、日期和时间以及地理位置,从而解答如下问题:
乍一看,似乎只要使用 SQL 即可解答这些问题。毕竟 SQL 的 CUBE、ROLLUP 和 GROUPING SETS 扩展都是专门为聚合多维数据而设计的。但请不要忘记,此处的某些数据存储在平面文件中,因此基于 SQL 的方法是不可行的。除此之外,观察上述问题,您会注意到个别问题的解答需要利用一年的历史数据。在实践中,这意味着您还需要访问包含历史数据的存档,这些历史数据源于事务数据,存储在各个不同的源中。在 SQL 中,管理所有这些数据源,以及将各数据源中的数据转为一致格式以支持统一的查询操作,这些工作费力且易于出错。
简而言之,这里的主要工作是:
数据仓库正是为执行这些任务而设计的。我们简要概括一下,数据仓库是一个专为处理分析查询(而非事务处理)而调优的关系数据库,通过定期刷新和更新保持是最新的,定期刷新和更新通过 ETL(提取、转换和加载)流程从源下载数据子集(通常在一周的某一天或白天、夜晚的一个预定时间调度执行)。要加载的数据转换为一致的格式,然后加载到数据仓库的目标对象中。填充数据仓库之后,一般可以通过多维数据集和维度等维度对象来查询该数据仓库。其示意图如下所示:
图 1 从不同源收集数据,将其转换为可供业务用户使用的有用信息。
具体来说,在本例中,合适的解决方案是一个简单的数据仓库,其中包含一个有几个维度的多维数据集。由于流量是这里的重点,您可能希望将传出流量定义为多维数据集的量度。为简单起见,本例中我们将根据所访问资源的大小测量传出流量。例如,若有人从您的站点下载一个 1MB 的文件,那么我们认为将产生 1MB 的传出流量。这类似于购买金额取决于所选产品的价格。金额通常是销售多维数据集的一个量度,而价格是产品的一个属性,产品通常用作该多维数据集中一个维度。与之相似的是,传出流量是我们的流量多维数据集的量度,而资源大小是资源的一个属性,资源将用作一个维度。
现在来看看维度,通过分析要回答的系列问题可以确定本示例中多维数据集所用的一组维度。因此,请仔细观察本节开始处列出的问题,您可能希望使用以下维度来组织多维数据集中的数据:
每条流量记录都将具有针对地理位置、资源以及日期和时间的具体值。说明一下,流量记录中的时间值指的是是访问资源的时间。
下一个关键步骤是定义为各维度聚合数据的级别,并将这些级别组织为层次结构。就地理维度而言,您可能会定义包含以下级别的层次结构(最先列出的是最高的级别):
资源维度的级别层次结构可能如下所示:
时间维度可能包含以下层次结构:
在更加复杂、现实的场景中,一个维度可能包含多个层次结构,例如,财年和日历年。但在这个特定的示例中,每个维度仅有一个层次结构。
您已确定了仓库中所需的对象,接下来就可以设计和构建这些对象了。这个任务可以使用 Oracle Warehouse Builder 来完成,从 Oracle Database 11g 第 1 版开始,这个工具就已经成为 Oracle Database 标准安装的一部分。但要启用它,您必须完成一些准备工作:
首先,需要解锁 Oracle Warehouse Builder 使用的数据库模式。Oracle Warehouse Builder 11g 第 1 版中使用的是 OWBSYS 模式,11g 第 2 版则同时使用了 OWBSYS 和 OWBSYS_AUDIT 模式。这些模式包含 OWB 设计和运行时元数据。可以作为 SYS 或 SYSDBA 连接到 SQL*Plus,然后使用以下命令完成此任务:
ALTER USER OWBSYS IDENTIFIED BY owbsyspwd ACCOUNT UNLOCK; ALTER USER OWBSYS_AUDIT IDENTIFIED BY owbsys_auditpwd ACCOUNT UNLOCK;
接下来,必须创建一个 Warehouse Builder 工作区。工作区包含一个或多个数据仓储项目的对象,在复杂环境中,可能要使用多个工作区。(面向 Windows 和 Linux 的 Oracle Warehouse Builder 安装和管理指南 提供了有关如何创建工作区的说明。可按照其中的说明新建一个工作区,将新用户作为工作区的所有者。)
现在,您可以启动 Warehouse Builder Design Center,这是 Oracle Warehouse Builder 的主要图形用户界面。单击 Show Details,用新建的工作区用户连接到 Design Center,提供必要的主机/端口/服务名称或网络服务名称。
我们先概述一下需要完成的任务,然后再继续解读。大致来说,本示例要完成的任务包括:
下面几节介绍如何完成上述任务,实现本文讨论的维度解决方案。在继续操作之前,必须先确定要使用哪种实现模型。实际上,您有两种选择:在关系表中存储实际数据的关系目标仓库,或者多维数据仓库。在后一种情况下,维度数据存储在 Oracle OLAP 分析工作区中。此特性在 Oracle Database 10g 和 Oracle Database 11g 中可用。就本示例而言,维度模型将作为关系目标数据仓库实现。
在这个初始步骤中,首先要创建一个新项目,或指责配置 OWB Design Center 中的默认项目。随后,您可以确定目标模式,该目标模式将用于包含目标数据对象:本文前面介绍的维度和多维数据集。
假设您已经决定使用默认项目 MY_PROJECT,让我们来继续创建目标模式。下面的步骤展示了创建目标模式的过程,随后还在 Design Center 中根据该模式创建目标模块:
完成上述步骤后,即在数据库中创建了 owbtarget 模式。(此外,owbtarget 用户还会出现在 Globals Navigator 的 Security->Users 节点下。)下一步是基于新建的数据库模式创建目标模块。简单说来,您将在 Warehouse Builder 中使用模块将要处理的对象组织为面向主题的组。以下步骤将说明如何基于 owbtarget 数据库模式构建 Oracle 模块:
完成上述步骤之后,TARGET_MDL 模块会出现在 Projects Navigator 的 MY_PROJECT->Databases->Oracle 节点下。如果展开该模块节点,您会看到可在其中创建的对象的类型。其中包括用于保存以下内容的节点:多维数据集、维度、表和外部表。
此时,您不仅需要从不同源中提取数据,还需要将提取的数据转换为可整合到单个数据源中的形式。因此,此任务通常包含以下阶段:
您首先需要制定一个提取源数据、转换数据并将其加载到数据仓库中的通用战略。也就是说,您必须首先制定战略决策,确定如何以最佳方式实现从数据源整合数据的任务。
就平面文件而言,您要制定的第一项决策或许就是如何将数据从这些源移至数据仓库中。下面是可供选择的方法:利用 SQL*Loader 或通过外部表。在这个具体示例中,使用外部表应该是更为可取的选择,因为从平面文件中提取的数据必须与关系数据相联接。回忆一下,本例假设将从数据库表和平面文件中提取源数据。
接下来,您需要决定是否为将使用的源数据对象定义一个源模块。尽管将源对象和目标对象分别放在不同的模块中通常被视为一种良好的习惯,但对于这个简单的示例来说,我们将在一个数据库模块中创建所有对象。
现在,让我们来进一步观察要访问的数据源。
如前所述,我们拥有一个网站,其资源托管在多台服务器上,每台服务器存储流量统计信息的方式各不相同。例如,一台服务器将其存储为平面文件,另一台服务器则将其存储在数据库中。举例来说,一个包含实时数据的名为 access.csv 的平面文件的内容可能如下所示:
User IP,Date Time,Site Resource 67.212.160.0,5-Jan-2011 20:04:00,/rdbms/demo/demo.zip 85.172.23.0,8-Jan-2011 12:54:28,/articles/vasiliev_owb.html 80.247.139.0,10-Jan-2011 19:43:31,/tutorials/owb_oracle11gr2.html
可以看到,上述文件包含有关用户访问资源的信息,并且这些信息以逗号分隔 (CSV) 格式存储。 而使用数据库代替平面文件的服务器可能会将相同的信息存储在结构如下的 accesslog 表中:
USERIP VARCHAR2(15) DATETIME DATE SITERESOURCE VARCHAR2(200)
您可能已经猜到了,在本例中,为了确定访问资源的用户的地理位置,IP 地址数据必不可少。具体来说,这使您能够推断出 IP 地址所属的地区、国家、城市乃至组织的地理位置。为了通过 IP 地址获得这样的信息,您可以利用一个免费或付费使用的地理位置数据库,现在有很多这样的数据库。此外,还可以利用用户在注册过程中提供的地理位置信息,也就是依靠您自己的数据库中存储的信息。但在这种情况下,您可能需要依靠用户的 ID 而非 IP 地址。
就本示例而言,我们将使用一个免费的地理位置数据库,该数据库可确定国家一级的 IP 地址范围,例如 MaxMind 的 GeoLite Country 数据库。(Maxmind 还提供了更精确的付费数据库,这些数据库包含国家级和城市级地理位置数据。)有关更多详细信息,可访问 MaxMind 网站。
GeoLite Country 数据库存储为一个 CSV 文件,其中包含公开分配的 IPv4 地址的地理数据,这样您能够根据 IP 地址确定用户所在的国家。为了利用此数据库,您需要下载压缩的 CSV 文件,进行解压缩,然后将其数据导入到您的数据仓库中。导入的数据将与通过本节前述的平面文件和数据库获得的 Web 流量统计数据相联接。
查看 GeoLite Country CSV 文件的结构,您可能会注意到,除了分配给特定国家的,由点分十进制表示的起始和结束 IP 地址定义的 IP 地址范围之外,还包括借助以下公式根据这些 IP 地址得出的相应 IP 编号:
IP Number = 16777216*w + 65536*x + 256*y + z
其中
IP Address = w.x.y.z
与使用直接 IP 地址相比,使用 IP 编号有个明显的好处,那就是,IP 编号是普通十进制数字,易于对比,这简化了确定相应 IP 地址属于哪个国家的任务。然而,问题在于我们的流量统计数据源存储的是直接 IP 地址,而非据此得出的编号。您需要转换 Web 流量数据,使转换的结果包含 IP 编号,而非 IP 地址。
下面是数据转换和联接的示意图:
图 2 Oracle Warehouse Builder 提取、转换和联接源数据。
我们记得,维度和多维数据集数据通常来自多个数据源。就本例而言,除了流量统计信息和地理位置数据之外,您还需要包含资源和地区信息的数据源。为此,可以假设您有两个数据库表:RESOURCES 和 REGIONS。假设 RESOURCES 表的结构如下:
SITERESOURCE VARCHAR2(200) PRIMARY KEY RESOURCESIZE NUMBER(12) RESOURCEGROUP VARCHAR2(10)
假设 REGIONS 表的定义如下:
COUNTRYID VARCHAR2(2) PRIMARY KEY REGION VARCHAR2(2)
上述表中的数据将与 Web 流量统计信息和地理位置数据相联接。
现在您已了解了源数据的结构和含义,我们将继续操作,在 Warehouse Builder 中定义所有必要的数据对象。我们首先为平面文件创建所需的对象。一般执行步骤如下:
要创建平面文件模块,请在 Design Center 中执行以下步骤:
现在,可在新建的平面文件模块中定义一个新的平面文件。首先,我们为本节前面提到的 access.csv 文件创建一个平面文件对象:
Name SQL Type SQL Length
USERIP VARCHAR2 15 DATETIME DATE SITERESOURCE VARCHAR2 200
此时,您可能希望将更改提交到信息库。选择 File->Save All 提交您的更改。
对包含地理位置数据的 GeoIPCountryWhois.csv 文件重复上述步骤,在向导的 Field Properties 屏幕中定义以下属性:
Name SQL Type SQL Length STARTIP VARCHAR2 15 ENDIP VARCHAR2 15 STARTNUM VARCHAR2 10 ENDNUM VARCHAR2 10 COUNTRYID VARCHAR2 2 COUNTRYNAME VARCHAR2 100
完成这些操作之后,在目标模块中定义外部表对象。这将在数据库中以表的形式提供平面文件数据。要根据此前创建的 ACCESS_CSV_FF 平面文件对象定义外部表,请执行以下步骤:
对 GEOLOCATION_CSV_FF 平面文件对象重复上述步骤。
现在,您已创建了所有必需的对象定义,接下来就需要将其部署到目标模式,之后才能使用它们。另外一个准备步骤是确保数据库中的目标模式具有创建和删除目录的权限。为此,可以作为 sysdba 连接到 SQL*Plus,并执行以下命令:
GRANT CREATE ANY DIRECTORY TO owbtarget; GRANT DROP ANY DIRECTORY TO owbtarget;
之后,您可以返回 Design Center 继续部署。以下步骤说明如何部署外部表:
如果部署成功完成,也就意味着您已经在数据库的目标模式中创建了外部表的定义,因此可以查询这些表。为确保到目前为止一切均如期实现,最好看看可通过新部署的表访问的数据。最简单的方法是在 Project Navigator 中右键单击一个外部表节点,然后从弹出菜单中选择 Data… 命令。
GEOLOCATION_CSV_ EXT 表不会有任何问题,该表包含大约 140,000 行记录,但对于 ACCESS_CSV_EXT 数据,您可能不会看到任何内容。为了确定问题出在哪里,您可能希望检查的第一个方面就是 ACCESS_CSV_EXT 的访问参数,可通过 ALL_EXTERNAL_TABLES 数据字典视图访问这些参数。这样,作为 sysdba 连接到 SQL*Plus 后,您可以执行以下查询:
SELECT access_parameters FROM all_external_tables WHERE table_name ='ACCESS_CSV_EXT';
其输出应如下所示:
records delimited by newline characterset we8mswin1252 string sizes are in bytes nobadfile nodiscardfile nologfile fields terminated by ',' notrim ("USERIP" char, "DATETIME" char, "SITERESOURCE" char )
查看上面的输出,您可能会注意到,DATETIME 字段未使用任何日期掩码,在访问格式与默认格式不同的日期数据时,这可能会引发问题。可以使用以下 ALTER TABLE 语句纠正该问题:
ALTER TABLE owbtarget.access_csv_ext ACCESS PARAMETERS (records delimited by newline characterset we8mswin1252 string sizes are in bytes
nobadfile
nodiscardfile nologfile fields terminated by ',' notrim ("USERIP" char, "DATETIME" char date_format date mask "dd-mon-yyyy hh24:mi:ss", "SITERESOURCE" char ) );
现在,返回 Design Center,如果您单击 Data-ACCESS_CSV_EXT 窗口中的 Execute Query 按钮,则会看到由源自 access.csv 文件的数据生成的一些记录行。
现在,为了完成创建数据源对象定义的任务,剩下的工作就是为本节前面提到的源数据库表 ACCESSLOG、RESOURCES 和 REGIONS 导入元数据。为此,可执行以下步骤:
完成上述步骤之后,ACCESSLOG、REGIONS 和 RESOURCES 对象一定会出现在 Projects Navigator 的 MY_PROJECT->Databases->Oracle->TARGET_MDL->Tables 节点下。
创建并部署了源对象定义之后,我们来构建目标结构。具体来说,您需要构建一个 Traffic 多维数据集,用于存储聚合的流量数据。在继续构建多维数据集之前,您必须先构建构成其边缘的维度。
记得本文开始时讲过,您需要定义以下三个维度来组织多维数据集内的数据:地理、资源和时间。以下步骤说明如何构建地理维度并为其加载数据:
Region Country
现在,您将定义一个 ETL 映射,以便从源数据载入 GEOGRAPHY_DM 维度。步骤如下所示:
Group Resource
最后,您需要创建一个时间维度。最简单的方法就是使用 Create Time Dimension 向导,该向导将为您定义一个时间维度对象以及用于加载此对象的 ETL 映射。有关如何创建和填充时间维度的详细信息,可参考“Oracle Warehouse Builder 数据建模、ETL 和数据质量指南”中的“创建时间维度”一节。
建立了维度之后,可执行以下步骤来定义多维数据集:
RESOURCE_DM GEOGRAPHY_DM TIME_DM
OUT_TRAFFIC with the data type NUMBER
对于维度,下一步要做的是创建一个映射,定义如何将源数据加载到多维数据集中。
现在,您需要设计 ETL 映射,以便转换源数据并将其载入多维数据集中。下面是需要设计的转换操作的列表:
如前所述,上述操作必须在一个映射中进行描述。在继续创建映射之前,我们首先来定义上述第二步所述的转换。这个转换将实现为一个 PL/SQL 函数。以下步骤描述如何不必离开 Design Center 即可完成此任务:
p NUMBER; ipnum NUMBER; ipstr VARCHAR2(15); BEGIN ipnum := 0; ipstr:=ipadd; FOR i IN 1..3 LOOP p:= INSTR(ipstr, '.', 1, 1); ipnum := TO_NUMBER(SUBSTR(ipstr, 1, p - 1))*POWER(256,4-i) + ipnum; ipstr := SUBSTR(ipstr, p + 1); END LOOP; ipnum := ipnum + TO_NUMBER(ipstr); RETURN ipnum; END;
现在,您可以创建一个映射,随后可在其中定义如何将源对象中的数据加载到多维数据集:
(INGRP2.USERIP BETWEEN INGRP1.STARTNUM AND INGRP1.ENDNUM) AND (INGRP2.SITERESOURCE = INGRP3.SITERESOURCE)
INGRP1.COUNTRYID,INGRP1.SITERESOURCE,INGRP1.DATETIME
TRUNC(INGRP1.DATETIME, 'DD')
RESOURCESIZE to OUT_TRAFFIC COUNTRYID to GEOGRAPHY_DM_NAME DATETIME to TIME_DM_DAY_START_DATE SITERESOURCE to RESOURCE_DM_NAME
至此,映射画布应如下图所示:
图 3 映射画布,显示了将源对象中的数据加载到多维数据集的 TRAFFIC_MAP 映射。
完成上述步骤后,也就按照映射中实现的逻辑使用来自源的数据填充了 TRAFFIC 多维数据集。然而,从实践的角度来讲,您更希望为事实表(也就是本例中的 TRAFFIC_TAB 表)填充数据。换句话说,多维数据集记录存储在事实表中。多维数据集本身仅仅是这里使用的维度数据的逻辑表示或可视化表示。
类似地,维度以物理的方式绑定到相应的维度表,这些维度表将维度数据存储在数据库中。维度表使用外键联接到事实表,构成了一种称为星型模式的模型(因为这种模式的示图类似于星型)。Oracle Database 的查询优化器能够为星型查询(对事实表和与之联接的维度表所发出的联接查询)应用强大的优化技术,从而为解答业务问题的查询提供了高效的查询性能。
业务智能是以支持决策为目的收集信息的过程,它需要适合其环境的基础。作为一种专门为此而设计的关系数据库,数据仓库提供了这样的基础:整合从不同源收集到的信息,并为业务用户提供对此类信息的访问,使他们能够作出更好的决策。
您在本文中看到,一个小型数据仓库可以仅包含一个多维数据集和少数几个维度,这些维度构成了该多维数据集的边缘。具体来说,您观察了一个示例,了解了如何将流量统计数据组织为多维数据集,而该多维数据集的边缘包括地理、资源和时间维度的值。如需了解基于此示例的更为高级的建议,请参见“使用 Oracle Warehouse Builder 进行高级维度设计”。
Yuli Vasiliev 是一名软件开发人员、自由撰稿人和顾问,目前专攻开源开发、Java 技术、业务智能 (BI)、数据库和面向服务的架构 (SOA)。他是《Oracle Business Intelligence:The Condensed Guide to Analysis and Reporting》(Packt,2010 年)的作者,另外还撰写了其他一系列关于 Oracle 技术的图书。。