级别: 初级 Marty Lurie, IBM IT 专家, Waltham, MA
2003 年 7 月 01 日 我们将侧重讨论一个使用 IBM DB2® Information Integrator(DB2 II)的案例研究。这些示例旨在开拓您的思路,并非演示一个推荐的生产环境。
引言
通过提供多服务器的单一视图,联邦数据库提高了效率。如我们在本文的
第 1 部分中所见,这不但简化了数据访问,而且联邦服务器可以非常有效地跨不同的数据库进行连接(join)和优化。为了让第 2 部分有趣,我们将侧重讨论一个使用 IBM DB2® Information Integrator(DB2 II)的案例研究。这些示例旨在开拓您的思路,而不是为了演示一个推荐的生产环境。因为我发现案例研究比抽象概念更加容易“铭刻在心”。
我们的难题是:我们的数据分布在多个服务器上,如图 1 所示:
图 1. 分布于多个数据源上的营销活动邮件列表数据
如果您选择接受任务,那么您的任务就是:
为营销活动创建邮件列表。此次营销活动的数据分布在多个数据源上。表 1 中特别列出了必需的数据源:
表 1. 邮件列表的数据源
|
内容
|
数据源
| | “勿发邮件”列表 | Oracle 9i | | 高价值客户 | Excel® 电子表格 | | 客户名单,记录系统 | Informix® XPS | | 客户信用等级 | Informix IDS |
您必须创建的营销活动根据信用等级、产生“高价值”客户的前期购物历史记录以及购买到的营销数据来提供不同的奖励。
销售列表必须以 XML 流的格式存在,并通过持久消息队列发送给营销活动的生产公司。
本案例研究的解决方案涉及以下步骤:
- 设置和测试数据源
- 开发实现营销活动的 SQL
- 将查询结果处理成 XML,并对 XML 流进行排队以便它可以由任何队列客户机读取。
正如在本文的第 1 部分中承诺的那样,这个案例研究的解决方案包括联邦插入、根据联邦连接得到的 XML 以及 XML 和 WebSphere® MQ。
当我的编辑看到这道难题时,她说:“您想把它放到第 2 部分里?”现在,您看到了。
首先,来自赞助方的几句话:DB2 Information Integrator 发布
DB2 Information Integrator 产品是在 2003 年 5 月 20 日发布的。这是
发布函,如果您自己没有找到它的话,这里有一段摘录:
“IBM DB2 Information Integrator V8.1 代表了下一代信息集成软件,它为 e-business on demand 提供了基础支柱。对变化的快速响应意味着商家不仅可以在企业中,而且可以在它的价值链中快速轻松地关联信息。DB2 Information Integrator 使公司可以在企业的内外对业务信息进行集成的、实时的访问。这样的信息可能位于各种数据源系统(如 Oracle 数据库、Microsoft® 电子表格、平面文件)中,并且分布于各种操作环境(如 Windows®、Linux、UNIX®、z/OS®)中。”
与其花费很多时间来描述这些特征,不如让我们言归正传,来
使用这些特征吧。
为本案例研究设置数据源
在第 1 部分中,我们设置了 Informix 数据源,所以这里我就不再重复了。请参阅设置 Informix 数据源的
那些指导。如果您喜欢使用命令行,而不是可用鼠标点击的界面,那么请参阅本文第 1 部分的
附录。
在本节中,我将描述:
- 对于“勿发邮件”列表,设置并使用 Oracle 数据源
- 对于销售信息,设置并使用 Excel 数据源
- 奖励的时候:设置并使用 ODBC 数据源
- 简短总结一下在 Informix 中如何创建客户表和信用表(请参阅第 1 部分以了解更多详细说明)。
设置并使用 Oracle 数据源
从本文的第 1 部分我们知道,DB2 Information Integrator 服务器对于远程服务器来说,就象一个运行查询的常规客户程序。为准备本案例研究我们需要的联邦环境包括设置一系列的远程数据源。别让我们被复杂性吓倒;DB2 Information Integrator 服务器可以和单个的远程数据源一样简单,其中用 DB2 Information Integrator 作为数据访问网关。设置数据源的步骤如下:
- 建立客户机连接。
- 配置
db2dj.ini 文件并设置 ORACLE_HOME 环境变量。
- 创建包装器。
- 创建服务器。
- 创建用户映射。
- 创建表昵称。
在构建了这个数据源之后,您将看到一个基于第 1 部分中两个先前示例和本示例的模式,而且如果给定所需的包装器,那么还应该能够配置联邦来访问任何数据源。
本节的内容虽然没有好到使您可以不必再去阅读优秀的文档,但我还是将尽力突出重点。关于“信息集成”,现在有一本红皮书,请参阅:
Getting Started on Integrating Your Information。
步骤 1:建立客户机连接
在 DB2 Information Integrator 服务器上安装 Oracle 客户机 SDK 相当容易。关键的一步是验证连接工作正常!
图 2显示了配置屏幕,这个配置屏幕还提供了一个简单的功能测试,用来测试到远程 Oracle 服务器的连接。
图 2 中突出显示的名称“foo”是一个节点名,对于在 Information Integrator 中定义配置以访问远程 Oracle 服务器来说,这个节点名是必需的。
图 2. 测试到 Oracle 服务器的连接
步骤 2:配置
db2dj.ini 文件
通过在安装了 Oracle 客户机之后再安装 DB2 Information Integrator(我用的是在发布之前的第三个也是最后一个 beta 发行版),安装程序能够自动检测客户机代码的位置,并在
db2dj.ini 文件中自动添加所需的 ORACLE_HOME 节。清单 1 显示了
db2dj.ini 文件的 Windows 示例:
清单 1.
db2dj.ini 文件包含了 Oracle 客户机的位置以及
第 1 部分中的 Informix 参数。
C:\Program Files\IBM\SQLLIB\cfg>type db2dj.ini
INFORMIXDIR=C:\PROGRA~1\Informix\CLIENT~1
INFORMIXSERVER=fliif
INFORMIXSERVER=flspy
INFORMIXSERVER=flxps
ORACLE_HOME=C:\oracle\ora92
|
当 DB2 II 和 DB2 V8 修订包 2 发行版(DB2 v8 fix pack 2 release)一起运行时,必须设置
ORACLE_HOME 环境变量。设置此变量的 Win32 和 UNIX 命令如下所示:
set ORACLE_HOME=c:\oracle\ora92
export ORACLE_HOME=/export/home/oracle
|
步骤 3:配置包装器
从
第 1 部分中我们了解到,DB2 Information Integrator 包装器告诉 DB2 Information Integrator 使用哪个程序库可以访问远程数据源。我将说明 Oracle 的设置,因为第 1 部分只包含了 Informix 远程服务器。
配置 DB2 Information Integrator,有图形界面也有命令行界面。要使用图形工具:
- 从命令行运行
db2cc
- 在 Windows 中,使用
开始 -> 程序 -> IBM DB2 -> General Administration Tools -> Control Center。展开左侧的树,左键单击
Federated Database Objects并选择
Create Wrapper选项。请见图 3。
图 3. 从 Control Center 创建包装器
下一个对话框定义了包装器类型。对于当前发行版的 Oracle(V8 和 V9),NET8 是正确的选项。请见图 4。
图 4. 对于 Oracle 包装器名选择 NET8
您的“私人老师”始终等候在
Show SQL按钮后面 - 请使用它!图 5 显示了一个示例,告诉您如何能够确切地知道正在运行的是什么命令,这样您就可以编写针对这个数据源或其它数据源的整个过程的脚本。
图 5. 创建包装器的“内幕”
步骤 4:创建服务器
现在我们需要标出远程 Oracle 系统的 IP 地址和端口。在创建服务器时,有很多选项可用。我最喜欢的是 DB2_MAXIMAL_PUSHDOWN。下面的图 6 显示了如何从 Control Center 进行这项操作。
图 6. 创建远程服务器
步骤 5:创建用户映射
用户映射提供了在远程 Oracle 实例的认证(
图 7)。对于远程数据库来说,DB2 Information Integrator 服务器和任何其它客户机在感觉上都是一样的。您不能指望不告诉远程服务器您是谁,就想让它“发货”,现在您能这么做了吗?我们将使用“scott”用户标识(这个标识是标准 Oracle 安装附带的)。不行,我的“scott”的密码不是“tiger”,您的应该也不是!用户映射 GUI 在 GA 代码中有一些小小的更改;这里的抓屏是取自最终 Beta 版的测试。
图 7. 创建用户映射
步骤 6:创建表昵称
对于现有的表,昵称是 DB2 Information Integrator 数据库用来引用远程表的本地句柄。对于全新的表,这个过程是简化的。
对于我们的案例研究,我们需要一个在数据库表中存储的“勿发邮件”列表。我们将从
db2=> 命令行在远程 Oracle 实例上创建并填充表。
首先,让我们创建表:
db2 => create table LURIE.do_not_mail (customer_num int)
options (REMOTE_SERVER 'oralin',
REMOTE_SCHEMA 'SCOTT', REMOTE_TABNAME 'donotmail')
DB20000I The SQL command completed successfully.
|
现在,还是从 db2 命令行,让我们使用方便的 DB2 语法来插入一些值:
db2 => insert into do_not_mail values (101), (105), (110)
DB20000I The SQL command completed successfully.
|
为了好玩,我们从表里选取值:
db2 => select * from do_not_mail
CUSTOMER_NUM
------------
101
105
110
3 record(s) selected.
|
如果表已经在远程服务器上存在,那么最后的任务就是创建表昵称,这样我们就可以引用远程表,如同它们是位于 DB2 Information Integrator 服务器上的。对于我们的案例研究来说,并不需要这么做,但是为了日后进行参考,我还是希望您做一下。同样,图形用户界面使得设置过程非常简单(图 8),将 SQL 保存起来可以避免将来定义时再去全部点击一遍。
图 8. 为现有的远程表创建昵称
下面您将看到的是(图 9)从远程目录中过滤名称的方法。我获取了本示例的全部远程目录;如果您在数据库中有多个表,您应该考虑使用这个过滤对话框来削减返回表的数量。
图 9. 过滤返回的远程表名称的数量
调试提示:如果您看到这条消息:
IBM][CLI Driver][DB2/NT] SQL1822N Unexpected error
code "12541" received from data source "oralin".
Associated text and tokens are "ORA-12541:
TNS:no listener ". SQLSTATE=560BD
|
请让您的 Oracle DBA 运行
lsnrctl start 命令。这条消息表示:当服务器启动时,Oracle TCP 远程侦听器没有自动启动。请把这个小提示放在某段脚本里,这样您就不会忘记了。
图 10 是创建昵称的最后两个对话框:
图 10. 创建昵称(续)
您可能已经猜到了,我是一个喜欢命令行的人,所以如果您想避免使用图形用户界面,则请参阅清单 2。
清单 2 中说明的是步骤 3 到步骤 6,这些都是为喜欢命令行的人提供的:
清单 2. 从命令行创建包装器、服务器、用户映射和昵称
-- get a database connection
connect to sample;
-- STEP 3 create the wrapper, indicating which dll to use
CREATE WRAPPER "NET8" LIBRARY 'db2net8.dll';
-- STEP 4 create the server that defines
-- the remote data source
-- notice the use of the MAXIMAL pushdown option
CREATE SERVER "oralin"
TYPE ORACLE VERSION '9i'
WRAPPER "NET8" OPTIONS ( NODE 'foo',
ADD DB2_MAXIMAL_PUSHDOWN 'Y' );
-- STEP 5 define the user mapping for authenticating
-- to the remote server
CREATE USER MAPPING FOR "LURIE"
SERVER "oralin" OPTIONS( REMOTE_AUTHID 'scott',
REMOTE_PASSWORD 'use_yours');
-- STEP 6 with the configuration defined above, set
-- up some tables in the remote server with nicknames
create nickname ora_dept for
"oralin"."SCOTT"."DEPT";
create nickname ora_card1 for
"oralin"."SCOTT"."card1";
select count(*) from ora_card1;
create nickname ora_card2 for
"oralin"."SCOTT"."ORA_CARD2";
select count(*) from ora_card2;
|
设置 Microsoft Excel 数据源
很多商业用户在把数据放到他们能看到的地方时是最开心的 - 这个地方就是 Excel。本例访问来自本地工作簿(worksheet)的 Excel 数据。
Excel 数据可以通过网络提供。Windows PC 上的本地 DB2 Information Integrator 服务器使这些数据象 DB2 表那样可被查看。这可能没有必要,但在某些环境下,能够提供这种访问可以解决一些难题。好了,这有我的一个朋友遇到的真实例子:
您收到了超过 200 个含有关于市场细分数据的电子表格。商务分析师对他们的杰作深感自豪 - 而您需要把所有这些数据都放到一个表中。您可以打开每一个电子表格并执行 200 多次剪切和粘贴,或者您也可以编写一个脚本来执行下面清单 3 所示的 DDL,再进行一系列的插入-选择(insert-select)或做一次联合(union)。随您选择,但我个人讨厌敲键盘,更不用说剪切和粘贴了,我当然会选择写脚本。
图 11 是我们原始的电子表格,其中有用客户号码标识的应该得到赠品的客户名单。
图 11. Microsoft Excel 电子表格
这段简单的 DDL 提供了对电子表格数据的 SQL 访问:
清单 3. 访问 Excel 数据的 DDL
create wrapper excelw library 'db2lsxls.dll';
create server excel_src wrapper excelw;
db2 => create nickname rc_mkt
( customer_num integer )
for server excel_src options (file_path
'c:\edrive\src\ii\mkt_list.xls', range 'a2:a20')
|
现在,让我们根据昵称进行选择:
db2 => select * from rc_mkt
CUSTOMER_NUM
------------
102
107
111
103
104
105
6 record(s) selected.
|
成功了,没用剪切和粘贴!
奖励关:设置 ODBC 数据源
对于那些没有本机 DB2 Information Integrator 驱动程序的远程服务器来说,ODBC 总是可以使用的。本示例演示如何设置到 Informix 的 ODBC 连接 - 您可以插入您需要的 ODBC 以访问您希望访问的数据库。
请记住,ODBC 驱动程序位于 DB2 Information Integrator 服务器上,并且连接到远程数据库。我使用远程 Informix 数据源,因为它容易得到,但这不是受支持的配置 - 在这里只是作为配置示例进行演示。
清单 4. 访问 ODBC 数据源的 SQL
db2 => create wrapper odbc library 'db2rcodbc.dll'
DB20000I The SQL command completed successfully.
-- the NODE is the odbc dsn name
db2 => create server ifxodbc type odbc version 3.0
wrapper ODBC options (node 'stores_odbc')
DB20000I The SQL command completed successfully.
db2 => create user mapping for lurie server ifxodbc
options (REMOTE_AUTHID 'informix',
REMOTE_PASSWORD 'use_yours' )
DB20000I The SQL command completed successfully.
|
passthru 功能可以让您在远程服务器上运行 SQL,就好像您直接连接到远程服务器一样。这对于绕过本机优化、验证远程服务器上的预测结果等很有好处。当您结束后,请别忘记关闭 passthru。
清单 5. passthru
db2 => set passthru ifxodbc
DB20000I The SQL command completed successfully.
db2 => select count(*) from customer
-----------------
28.
1 record(s) selected.
db2 => set passthru reset
db2 => create nickname odbc_customer for
ifxodbc."informix"."customer"
DB20000I The SQL command completed successfully.
|
在 Informix 中设置客户表和信用表
在为本案例研究设置客户表和信用等级表时,我们将练习 DB2 II 的更多功能。我们将说明在远程服务器上创建表以及将数据插入远程服务器的能力。
创建表并插入数据
DB2 Information Integrator 服务器可以创建表、插入、更新和删除所有数据,而无需离开您所选择的
db2 => 提示符或 DB2 GUI,二者用起来都很方便。
为了说明本示例,让我们把数据从 Oracle 移动到 Informix。很抱歉让您知道我是有一些偏见的,但我确实认为把数据移出 Oracle,移入 Informix 或者 DB2 UDB 是个很好的主意。
表的创建
无需离开 DB2 Information Integrator 环境,您就可以在远程服务器上创建表。在本例中,我们在 IDS 上创建表:
db2 => create table lurie.credit_rating (
customer_num int, credit_rank int)
options ( remote_server 'rcfliif' ,
remote_schema 'informix',
remote_tabname 'cust_credit' );
DB20000I The SQL command completed successfully.
|
利用 INSERT-SELECT 填充表
现在我们利用 INSERT-SELECT 填充远程表。下面的 SQL 将从远程 Oracle 表中抽取两列,并将这些数据填充到刚刚添加的 Informix 表中。
请注意我们得到了一个错误!
db2 => insert into credit_rating (customer_num, credit_rank)
select superkey, c3 from ora_card2
DB21034E The command was processed as an SQL statement because
it was not a valid Command Line Processor command. During SQL
processing it returned:
SQL20190N Federated insert, update, or delete operation
cannot be compiled because of potential data inconsistency.
SQLSTATE=0A503
|
如果我们在插入过程中失败,DB2 Information Integrator 可以让我们免遭错误。因为插入是一项很容易重复的事务,所以我们将用一个服务器选项来克服这个错误。您可以通过 GUI 的
Add server options对话框来完成这个操作,或就从命令行执行下面的命令:
db2 => altER SERVER "rcfliif" OPTIONS
( ADD IUD_APP_SVPT_ENFORCE 'N')
DB20000I The SQL command completed successfully.
|
现在我们将再次执行 INSERT-SELECT:
db2 => insert into credit_rating
(customer_num, credit_rank)
select superkey, c3 from ora_card2
DB20000I The SQL command completed successfully.
db2 => select count(*) from credit_rating
1
-----------
50001
1 record(s) selected.
|
数据如下所示:
db2 => select * from credit_rating
where customer_num > 100 fetch first 10 rows only
CUSTOMER_NUM CREDIT_RANK
------------ -----------
101 2
102 3
103 1
104 2
105 3
106 1
107 2
108 3
109 1
110 2
10 record(s) selected.
|
为本案例研究创建客户表
为了创建销售列表,客户表是我们需要进行连接的四个表中的最后一个。客户表是什么样的呢?我想您是不会这么问的:
图 12. XPS 中的客户表
这是一个很简单的昵称。本文的第 1 部分提供了更多关于设置 Informix 昵称的背景知识。
-- set up the customer table nickname
db2 => create nickname rc8_customer
for "rc_xps"."informix"."customer"
DB20000I The SQL command completed successfully.
|
邮件列表连接
现在进行“超级查询”(mega-query)。请注意我在 SQL 中穿插的注释。我已经将它们用粗体标出。
-- the rc8_customer table is the system of
-- record for addresses
-- so get all the address fields there
select x.fname,
x.lname,
x.lname,
x.company,
x.address1,
x.city,
x.state,
x.zipcode,
-- use the CASE SQL statement to put in the logic?
-- here is the magic to deal with each customer
-- situation, on the marketing list, or a range of
-- credit ratings
case
-- if the customer is on the marketing list send
-- the "super" mailing
when x.customer_num in
(select customer_num from rc_mkt ) then 'super'
-- if the customer has a good credit, a 1 of 3
-- then send a "deluxe" offer, not quite as good as super
when i.credit_rank = 1 then 'deluxe'
-- average rating, a 2, send standard mailing
when i.credit_rank = 2 then 'standard'
-- for the 3 rankings, they owe us money from the last
-- order
when i.credit_rank = 3 then 'collection letter'
else 'standard'
end
-- join condition across the the tables
from rc8_customer x, credit_rating i
where x.customer_num = i.customer_num
-- now suppress all maling to those on the do not mail list
and i.customer_num not in
( select z.customer_num from do_not_mail z)
;
|
结果如下所示
select x.fname, x.lname, x.company, x.address1, x.city, x.state, x.zipcode, case
when x.customer_num in (select customer_num from rc_mkt ) then 'super' when i.c
redit_rank = 1 then 'delux' when i.credit_rank = 2 then 'standard' when i.cred
it_rank = 3 then 'collection letter' else 'standard' end from rc8_customer x, c
redit_rating i where x.customer_num = i.customer_num and i.customer_num not in (
select z.customer_num from do_not_mail z)
FNAME LNAME COMPANY ADDRESS1 CITY
STATE ZIPCODE 8
--------------- --------------- -------------------- -------------------- ------
--------- ----- ------- -----------------
Carole Sadler Sports Spot 785 Geary St San Fr
ancisco CA 94117 super
Philip Currie Phil's Sports 654 Poplar Palo A
lto CA 94303 super
Anthony Higgins Play Ball! East Shopping Cntr. Redwoo
d City CA 94026 super
George Watson Watson & Son 1143 Carver Place Mounta
in View CA 94063 delux
Charles Ream Athletic Supplies 41 Jordan Avenue Palo A
lto CA 94304 super
Donald Quinn Quinn's Sports 587 Alvarado Redwoo
d City CA 94063 collection letter
Jane Miller Sport Stuff Mayfair Mart Sunnyv
ale CA 94086 delux
Frances Keyes Sports Center 3199 Sterling Court Sunnyv
ale CA 94085 super
Margaret Lawson Runners & Others 234 Wyandotte Way Los Al
tos CA 94022 delux
Lana Beatty Sportstown 654 Oak Grove Menlo
Park CA 94025 standard
(... rows not shown)
|
DB2 可视化解释工具(DB2 Visual Explain)显示了使用一个新的操作符 RPD 来访问 Excel 数据,如图 13 所示:
图 13. 邮件列表连接的 Visual Explain
让我们将此查询放入一个视图以备将来引用。IBM 建议根据远程表来创建视图,这要优于根据远程视图来创建视图。
同样,通过便利的 db2 命令提示符,我们创建下面的视图:
drop view v_mkt_list;
create view v_mkt_list (fname, lname, company,
addr, city, st,zip, mail_type) as
select x.fname,
x.lname,
x.lname,
x.company,
x.address1,
x.city,
x.state,
case
when x.customer_num in (select customer_num from rc_mkt )
then 'super'
when i.credit_rank = 1 then 'delux'
when i.credit_rank = 2 then 'standard'
when i.credit_rank = 3 then 'collection letter'
else 'standard'
end
from rc8_customer x, credit_rating i
where x.customer_num = i.customer_num
and i.customer_num not in
( select z.customer_num from do_not_mail z)
;
|
处理大型表和脏数据
在联邦的设计方面有两个较大的难题:VLDB(very large databases,特大型数据库)和脏数据。通过良好的规划和体系结构,这些问题可以得到控制。
大型表
在 VLDB 环境中,一个无共享(shared nothing)的体系结构必然需要扩充处理能力以执行“想方设法把事情搞定(boil the ocean)”式的查询。请参阅我的文章
在 Linux 上模拟 MPP 处理以获取有关无共享体系结构的更多信息。如果我们尝试将大型数据库和远程数据库进行连接(join),那么就会在我们的 DB2 Information Integrator 服务器上汇聚成一股数据洪流。
有一个简单的变通办法。在无共享 MPP 服务器上创建一个表,然后从远程数据库执行插入-选择操作,将数据插入 MPP 环境。然后和 MPP 环境进行连接,接着就可以享受运行高度可伸缩的无共享服务器带来的快速响应并接受最终用户的赞誉之辞了。
脏数据
联邦的第二个问题是“脏数据”。其实,它也没什么了不起的,无非就是系统 A 的
customer_number 是客户号码,它和系统 B 的
customer_number 的含义完全不一样,后者是社会保险号。DBA 将做什么呢?
DBA 真正需要知道的是元数据 - 并采用正确的工具进行数据清理(data scrubbing)。有大量的抽取、转换和载入(ETL)工具可以用来帮助解决这个问题。我们不应该忽视 DB2 本身所提供的此类功能。
soundex 函数就是一个可以用来连接名字的简单工具的好例子。连接“LURIE”和“Laurie”和“Luria”的尝试会失败。即使这些名称都转换为大写,连接还是会失败。soundex 能如何提供帮助呢?它将所有的字符转换成大写,去掉元音,然后使用每个字母的发音匹配分值。
以下是一个正常工作的 soundex() 示例:
create table soundex_test( lname char(18) )
DB20000I The SQL command completed successfully.
insert into soundex_test values
('LURIE'), ('Laurie'), ('Luria')
DB20000I The SQL command completed successfully.
select * from soundex_test
LNAME
------------------
LURIE
Laurie
Luria
3 record(s) selected.
select soundex(lname) from soundex_test
1
----
L600
L600
L600
3 record(s) selected.
|
所有这三个名称都产生了相同的 soundex() 结果,这样我们的连接就可以顺利完成了。您也可以编写自己的用户定义函数来进行数据清理。提醒您一下:如果您需要最高的可能匹配率,而且误检(false positive)要降到最低,那么您确实需要评估一下进行数据清理的产品,除非您有太多的空闲时间,而且喜欢重复别人已做过的工作。
根据联邦连接创建 XML 文档
XML 已经成为系统间通信的最佳格式。交换数据有比自我描述(self-describing)数据更好的吗?XML 当然受到了低信噪比的影响,它比较冗长烦琐,但还是获得了普遍的接受。
DB2 有多个内建的函数来将数据转换为 XML。现在让我们来看一下 rec2xml() 函数。
rec2xml() 是一个非常快速方便的方法,可把表数据转换为 XML。我们的营销活动是由我们创建的视图定义的。采用 rec2xml(),只要一步就可以得到 XML 流:
select rec2xml ( 1.0, 'COLATTVAL','MKT_MAILING'
, fname
, lname
, company
, addr
, city
, st
,zip
,zip
, mail_type)
from v_mkt_list;
|
以下是一些样本输出:
<MKT_MAILING>
<column name="FNAME">Frank </column>
<column name="LNAME">Lessor </column>
<column name="COMPANY">Phoenix University </column>
<column name="ADDR">Athletic Department </column>
<column name="CITY">Phoenix </column>
<column name="ST">AZ</column>
<column name="ZIP">85008</column>
<column name="MAIL_TYPE">standard</column>
</MKT_MAILING>
|
这也可以封装在视图中,如下所示:
create view mkt_xml (mail_label_xml) as (
select rec2xml ( 1.0, 'COLATTVAL','MKT_MAILING'
, fname
, lname
, company
, addr
, city
, st
,zip
,zip
, mail_type)
from v_mkt_list )
;
|
将它们组合起来:通过 WebSphere® MQ 发布联邦 XML
现在我们准备将所有这些组合起来,并将我们的 XML 营销活动发给进行邮递的公司。通信方法是 IBM WebSphere MQ。这是一个持久队列(persistent queue)。
持久队列是什么?可以把它看成“吃了兴奋剂”的 UNIX® 命名管道。这个队列可以包含很多相异的消息,并且不用“破坏”消息就可读取队列。它可用于发布-订阅式的消息传递或点到点式的消息传递。它是一个非常强大的消息传递系统。
为了把 XML 发布到 WebSphere MQ,我们需要做一些设置工作。我们将采用最简单的途径并全部在本地进行:
- 把 WebSphere 安装在和 DB2 相同的服务器上。请查阅 IBM Web 站点或联系您的 IBM 团队以获得评估软件。
- 请找到 DB2 附带的 MQ 功能。在 Windows 中,这个文件是
ma0f_nt.zip 。解压缩这些二进制文件并安装它们。
- 切换到 DB2 cfg 目录,并运行
enable_mqfunctions ,如下所示:
à\IBM\SQLLIB\cfg>enable_mqfunctions -n sample -u lurie -p use_yours
*** Please wait: creating queue manager (DB2MQ_DEFAULT_MQM) ...
*** Please wait: starting the queue manager (DB2MQ_DEFAULT_MQM) ...
(0) db2mq UDFs were found
-- Create MQ Functions ...
Validate MQ Functions ...
Validate successfully.
*** Please allow a few seconds to clean up the system ...
|
如果您需要手动启动 WebSphere MQ,命令为:
#start the queue and command server
strmqm DB2MQ_DEFAULT_MQM
strmqcsv DB2MQ_DEFAULT_MQM
|
现在您等待已久的时刻到了 - 把 XML 发布到 WebSphere MQ。这个命令太简单了,简直有点虎头蛇尾。
C:\edrive\src\ii>db2 select db2mq.mqsend ( mail_label_xml ) from mkt_xml
1
-
1
(... rows not shown)
1
1
1
25 record(s) selected.
|
现在该做什么?我们可以使用 MQ API Exerciser 看一下实际的结果,MQ API Exerciser 在“MQ first steps”启动器中很容易找到。启动 API Exerciser,连接 DB2 队列,并执行 MQGET,如图 14 所示。
图 14. 对 DB2 队列执行 MQGET
图 15是来自队列的实际消息,这正是我们完成本次案例研究所需要的。我们对三个不同的关系数据源和一个 Excel 电子表格进行了联邦,将连接输出转换为 XML,并将这个 XML 发布到持久消息队列中,这样其他人就可以访问这一信息了。哇,我们完成了。
图 15. XML 消息的内容显示了联邦的数据
结束语
我希望这两篇文章能给您一些启示,让您知道如何把不同服务器的数据合并起来,以便使 DBA 的工作更轻松。
我们已了解了多数据源、连接、插入、优化以及一个案例研究。我们了解了大数据量的含义以及数据清理的需要。我们把远程数据合并成 XML 流,并将它发布到持久消息队列。
请随意尝试一下。它应该够您忙上一阵子了,这样我就可以写下一篇文章了。
相关信息
关于作者  | 
|  |
Marty Lurie的计算机生涯始于制造纸带孔屑,那时他正在 IBM 1130 上尝试编写 Fortran 程序。他的日常工作是作为 IBM Data Management 的一名 IT 专家,不过如果再追问几句,他就会承认他主要是和计算机打交道。他最喜欢的程序是一个他自己编写的把他的膝上型计算机连接到 Nordic Track 的程序(这台膝上型计算机的体重减轻了两磅,少了 20% 的“胆固醇”)。Marty 是 IBM 认证的 DB2 DBA、IBM 认证的商业智能解决方案专家(Business Intelligence Solutions Professional)以及 Informix 认证专家(Informix-certified Professional)。可以通过
lurie@us.ibm.com和 Marty 联系。
|
对本文的评价
|