 | 级别: 初级 Dan A. Simchuk (simchuk@us.ibm.com), 高级软件工程师, IBM Corporation
2004 年 12 月 01 日 本文主要讨论为 IBM®DB2® Universal Database™ (UDB)(包括 UNIX®、Linux® 和 Windows® 上的实现)提取、转换和加载(ETL)数据,还将介绍 IBM 和其他厂商提供的主要选项、技术和产品。作者 Dan Simchuk 将详细阐述为大型资料库获取数据的实用选项 —— 在单分区和多分区系统上运行的数据仓库、数据集市和操作性数据存储等。此外,还将探讨 ETL 的未来发展和实现 ETL 的一些新方法。
简介
在有效地使用数据资料库之前,通常需要从很多数据源创建或者更新资料库。最常见的情况是,在外部系统上累积数据(供以后更新资料库使用),这些数据的格式也与资料库的要求有所不同。获得这些数据并将其转化成有用、一致、准确的数据的过程通常称为 ETL,其中的三个字母分别代表提取(Extraction)、转换(Transformation)和加载(Load)。
提取就是从源系统中获取数据(无论是何种格式)。这个过程可能很简单,只需要从数据库或者电子表格转储文本文件(flat file);也可能很复杂,需要建立与外部系统的联系,然后控制数据到目标系统的传输。
转换通常不仅仅是数据格式的转换(虽然这是将数据导入系统的关键一步)。外部系统中的数据可能包含不一致或者不正确的信息,这取决于外部系统上实施的检查和平衡。转换步骤的一部分是"净化"或"拒绝"不符合条件的数据。这个阶段常用的技术包括字符检查(拒绝包含字符的数值性数据)和范围检查(拒绝超出可接受范围的数据)。被拒绝的记录通常存放在单独的文件中,然后使用更复杂的工具处理,或者手工改正问题。然后将这些数据合并到已转换集合中。
加载阶段将获取并转换的数据存放到新的数据存储中(数据仓库、数据集市等)。对于 DB2 UDB,该过程可以用 SQL 命令(IMPORT)、工具(LOAD)或集成工具(Data Warehouse Manager 和 Information Integrator)来完成。另外,整个 ETL 过程也可使用第三方应用程序来完成,这样做通常可以减少编程,或者不需要自己编程。
ETL 过程可能非常简单,只需要将一些数据从一个表传递到相同系统中的另一个表。也可能非常复杂,需要从数千英里之外的完全不同的系统获取数据,然后重新安排和重新格式化,使其符合完全不同的系统。下面将描述完整的 ETL 到 DB2 UDB 的方法(但不一定没有遗漏)。只要有可能,我会提供有关该方法的详细信息的链接。
如何使用本文
下面的每一节(同时也列在上方的侧栏中)都包括来自不同 IBM 资源的信息,如网页、红皮书、技术手册和白皮书等。为了方便读者,本文在适当的情况下重复列出了这些信息。这种情况下,如果有其他可用的资源,那么在每小节标题后面都给出获得这些资源的链接。
参考资料一节中也列出了所有相关资源。
 |
例子
在后面的几节中,用到了一个示例数据仓库,
附录 A 中将对其进行描述。
|
|
DB2 IMPORT
有关的更多信息,请参阅
DB2 Data Movement Utilities Guide and Reference Manual(第 2 章)
和
DB2 Command Reference Manual
。
DB2 UDB 导入(IMPORT)工具使用 SQL INSERT 语句将输入文件中的数据写入表或者视图中。如果目标表或视图已经包含这些数据,那么可以选择替换原来的数据或者将这些数据追加到原有数据后面。
导入工具把输入文件中的数据插入表或者可更新的视图。如果接收到入数据的表或视图已经包含数据,可以代替原来的数据或者追加。
导入数据需要以下信息:
- 输入文件的路径和名称。
- 目标表或者视图的名称或别名。
- 输入文件中的数据格式,这种格式可以是 IXF、WSF、DEL 或 ASC。
- 输入数据要插入表中,还是要插入视图中,要输入数据更新还是替换表或视图中的原有数据。
- 如果通过应用程序编程接口(API)aqluimpr 调用该工具,那么还需要一个信息文件名。
- 如果处理类型化的表,可能需要提供处理所有结构化类型的方法或顺序。从上到下、从左到右地处理上级表,按层次结构处理子表,这样的顺序称为遍历顺序。在表层次结构间移动数据时,这个顺序很重要,因为它决定了移动的数据相对于其他数据的位置。在处理类型化的表时,可能还需要提供子表清单。该清单指出将哪一个子表或者属性导入数据。
您还可以规定:
- 导入数据的方法:列位置、列名或相对列位置。
- 向表提交更改前插入的行数。定期请求 COMMIT 会减少重要操作中因为失败或者出现 ROLLBACK 所损失的行数。还可以防止因为处理的输入文件过大而导致 DB2 日志被填满。
- 开始导入前要跳过的文件记录数。如果出现错误,可以从成功导入并提交的最后一行后面重新开始导入操作。
- 要插入数据的表或视图的列名。
- 信息文件名。DB2 执行数据导出、导入、加载、绑定或恢复操作时,可以指定一个信息文件,DB2 会创建该文件中包含与这些操作有关的错误、警告和提示信息。应在 MESSAGES 参数中指定这些文件名。这些信息文件是标准的 ASCII 文本文件。信息文件中的每条信息都从一个新行开始,包含 DB2 信息检索设施所提供的信息。可以使用操作系统提供的打印过程进行打印,并且可以使用任何 ASCII 编辑器进行查看。
DB2 IMPORT 命令
图 1. DB2 IMPORT 命令
DB2 IMPORT 例子
DB2 IMPORT 要求要填充的表已经存在。一旦执行了数据库的 DDL,将逗号分隔数据导入多个表的典型 DB2 脚本如下所示:
CONNECT TO Library;
DELETE FROM Volume;
IMPORT FROM Volume.csv OF DEL INSERT INTO Volume;
DELETE FROM Story;
IMPORT FROM Story.csv OF DEL INSERT INTO Story;
DELETE FROM Volume_Title;
IMPORT FROM Volume_Title.csv OF DEL INSERT INTO Volume_Title;
DELETE FROM Volume_Publisher;
IMPORT FROM Volume_Publisher.csv OF DEL INSERT INTO Volume_Publisher;
DELETE FROM Author;
IMPORT FROM Author.csv OF DEL INSERT INTO Author;
DELETE FROM Story_Title;
IMPORT FROM Story_Title.csv OF DEL INSERT INTO Story_Title;
COMMIT;
TERMINATE;
|
DB2 LOAD
有关的更多信息,请参阅
DB2 Data Movement Utilities Guide and Reference Manual(第 3 章)
和
DB2 Command Reference Manual
。
LOAD 工具可以高效地将大量数据转移到新建表中,或者插入已经包含数据的表中。该工具能够处理大多数数据类型,其中包括大型对象(LOB)和用户定义类型(UDT)。LOAD 工具比 IMPORT 工具速度快,因为它直接将格式化的页写入数据库,而 IMPORT 工具要执行 SQL INSERT 操作。LOAD 工具不会激活触发器,也不执行参照检查或表约束检查(除了验证索引的惟一性)。LOAD 过程包括 4 个不同的阶段。
加载过程的 4 个阶段(加载、构建、删除和索引复制)
Load 操作开始执行时,目标表处于 load-in-progress 状态。如果表有约束条件,那么表会进入 check-pending 状态。如果指定 ALLOW READ ACCESS 选项,那么表会进入 read-access-only 状态。
图 2. DB2 LOAD 的执行阶段
- 加载阶段将数据写入表。加载过程中,数据被装载到表中,如果需要的话,还可以搜集索引键和表的统计信息。按照 LOAD 命令中的 SAVECOUNT 参数指定的时间间隔来建立保存点(save point)或者一致性点(point of consistency)。保存点上生成信息,说明当前已经成功加载了多少行。对于使用 FILE LINK CONTROL 定义的 DATALINK 列,可以对非空列值执行链接操作。如果操作失败,可以重新启动加载操作,RESTART 选项自动从上一次成功的一致性点重新启动加载操作。TERMINATE 选项滚回失败的加载操作。
- 构建阶段生成索引。在构建阶段,按照加载阶段搜集的索引键生成索引。加载过程中索引键被排序,并且收集了索引的统计信息(如果 INDEXES 选项指定了 STATISTICS YES)。这些统计信息与 RUNSTATS 命令收集的信息类似。如果构建阶段失败,RESTART 选项自动从适当的位置重新启动加载操作。
- 删除阶段将表中造成惟一键冲突或者 DATALINK 冲突的行删除。如果指定了异常表,则有惟一键冲突的行会被放在异常表中,关于被拒绝行的信息被写入信息文件。加载过程结束后,还要查看这些信息,解决存在的问题,然后向表中插入正确的行。不要试图删除或修改加载工具创建的任何临时文件。某些临时文件对于删除阶段非常重要。如果删除阶段失败,RESTART 选项可以从适当的位置重新启动加载操作。提示:每个删除事件都记录到日志中,如果有大量记录违反了惟一性条件,那么删除阶段中日志文件可能被填满。
- 索引复制阶段将索引数据从系统临时表空间复制到原始表空间。只有在加载操作中指定 READ ACCESS 选项,并为索引创建指定了系统临时表空间时,才会执行这个步骤。
加载数据需要以下信息:
- 输入文件、命名管道或设备的路径和名称。
- 目标表的名称或别名。
- 输入源的格式,可以是 DEL、ASC、PC/IXF 或 CURSOR。
- 输入数据是追加到表中,还是代替原来的数据。
- 如果通过应用程序编程接口(API)db2Load 调用该工具,那么还需要指定信息文件名。
DB2 LOAD 命令
图 3. DB2 LOAD 命令
DB2 LOAD 例子
与 IMPORT 相同,LOAD 工具也要求表的结构已经建立。对于
附录 A 中定义的数据库,将逗号分隔的数据 LOAD 到多个表中的典型脚本如下所示:
CONNECT TO Library;
DELETE FROM Volume;
LOAD FROM Volume.csv OF DEL INSERT INTO Volume;
DELETE FROM Story;
LOAD FROM Story.csv OF DEL INSERT INTO Story;
DELETE FROM Volume_Title;
LOAD FROM Volume_Title.csv OF DEL INSERT INTO Volume_Title;
DELETE FROM Volume_Publisher;
LOAD FROM Volume_Publisher.csv OF DEL INSERT INTO Volume_Publisher;
DELETE FROM Author;
LOAD FROM Author.csv OF DEL INSERT INTO Author;
DELETE FROM Story_Title;
LOAD FROM Story_Title.csv OF DEL INSERT INTO Story_Title;
COMMIT;
TERMINATE;
|
在数据分区环境中加载数据
有关的更多信息,请参阅
DB2 Data Movement Utilities Guide and Reference Manual(第 4 章)
和
Quick Beginnings for DB2 Servers Manual(第 10 章)
。
在分区数据库中,大量的数据分散在多个分区中。分区键用来确定数据的各部分位于哪一个数据库分区中。将数据加载到正确的数据库分区之前,必须先对数据进行分区。
分区加载的概念和术语
讨论在分区数据库环境中加载工具的行为和操作时,要用到以下术语:
- 调度分区是用户连接并在其上执行加载操作的数据库分区。在 PARTITION_AND_LOAD、PARTITION_ONLY 和 ANALYZE 模式下,通常会假定数据文件在这个分区上,除非加载命令中指定了 CLIENT 选项。指定加载命令的 CLIENT 选项表明要加载的数据位于远程连接的客户机上。
- 在 PARTITION_AND_LOAD、PARTITION_ONLY 和 ANALYZE 模式下,预分区代理将读入用户数据,并以轮询的方式将这些数据分发给数据分区的分区代理。这些过程都是在调度分区上执行的。任何加载操作都只允许每个分区最多能有一个分区代理。
- 在 PARTITION_AND_LOAD、LOAD_ONLY 和 LOAD_ONLY_VERIFY_PART 模式下,加载代理在每个输出分区上运行并调度该分区上的数据加载。
- PARTITION_ONLY 加载操作过程中,文件代理加载在每个输出分区上运行。它们从分区代理接收数据并写入所在分区的文件。
- 文件传输命令代理在调度分区上运行,负责执行文件传输命令。
图 4. 分区数据库加载概略图。预分区代理读入源数据,数据被近似地分成两半传递给两个分区代理,分区代理对数据进行分区,并将它们发送到三个数据库分区中的一个分区中。每个分区的加载代理加载数据。
在分区数据库环境中加载数据时,加载工具可以执行以下操作:
- 并行对输入数据分区。
- 在相应的数据库分区中同时加载数据。
- 从一个系统将数据传输到另一个系统。
- 分区数据库加载操作发生在两个阶段:建立阶段获取分区资源(如表锁),加载阶段将数据装入分区。可以使用 LOAD 命令 ISOLATE_PART_ERRS 选项决定这两个阶段出现错误时该如何处理,一个或多个分区的错误对其他没有错误的分区的加载操作有什么影响。
将数据加载到分区数据库可以选择使用以下模式:
-
PARTITION_AND_LOAD:对数据进行分区(可以并行),并将它们加载到相应的数据库分区中。
-
PARTITION_ONLY:对数据进行分区(可以并行),并将它们输出到写入每个加载分区上的指定位置的文件中。每个文件都包括分区头,规定数据是如何分区的,可以使用 LOAD_ONLY 模式将这些文件加载到数据库中。
-
LOAD_ONLY:假设数据已经分区,跳过分区过程,将数据同时加载到相应的数据库分区中。
-
LOAD_ONLY_VERIFY_PART:假定数据已经分区,但数据文件没有包含分区头。跳过分区过程,数据被同时装载到相应的数据库分区中。在加载过程中,要检查每一行,查看它们是否在正确的分区中。如果制定转储文件类型限定符,那么包含分区冲突的行将存放到一个转储文件中。否则就要抛弃这些行。如果某个加载分区存中发生分区冲突,那么要将一个警告写入该分区的加载信息文件中。
-
ANALYZE:生成优化的可能跨越所有数据库分区的分区映射。
DPF LOAD 的例子
下面的例子将
附录 A 所述的 "Story" 数据装载到一个 5 分区系统的两个分区中。
LOAD FROM LOAD.DEL OF DEL
REPLACE INTO Story
PARTITIONED DB CONFIG
PARTITIONING_DBPARTNUMS (3,4)
|
下图说明了处理这个多分区加载任务所产生的不同代理。
图 5. 分区加载过程
DB2 Business Intelligence 产品
关于 DB2 BI 产品的最新信息,请参阅
DB2 Business Intelligence 主页。
IMPORT 和 LOAD 工具只能处理 ETL 的加载部分,与此相比,DB2 Business Intelligence Products 提供了更健壮的 ETL 方法。Data Warehouse Center 提供了一个完整的过程,支持数据仓库的创建、数据源和目标的定义、数据的转换和移动,以及数据仓库的日常维护。Data Warehouse Manager 又添加了 Information Catalog 来管理元数据。最后,DB2 UDB Data Warehouse Edition (DWE) 结合了 DB2、OLAP Tools 和 Information Integration Tools 的所有这些特性,并且可以统一安装。
关于使用 Data Warehouse Center 创建数据仓库的完整教程,请参阅 DB2 Manual 中的
BI Tutorial: Introduction to the Data Warehouse Center
。该教程是用 DB2 UDB v8 提供的示例数据仓库介绍了下图中的每个步骤。
图 6. 创建数据仓库的步骤
另一个 DB2 手册
BI Tutorial: Extended Lessons in Data Warehousing
,描述了其他过程,如下图所示。
图 7. 其他数据仓库步骤
在上面几节中,手工定义了 Library 数据仓库中的表,然后使用调用 IMPORT 或 LOAD 工具的脚本填充这些表。通过 Data Warehouse Center,这些任务可以用图形化的界面完成。下面几节将简要说明如何利用 WDC 开发和维护 Library 数据仓库。有关的更多细节,请参阅上面提到的教程手册。
定义仓库安全性
数据仓库安全由仓库控制数据库来管理。一旦指定了该数据库,它就会保存仓库的元数据,其中包括用户和口令。因此,在访问 Data Warehouse Center (DWC) 之前,必须指定或创建一个仓库控制数据库,然后定义用户和组,并分配适当的权限。
创建仓库数据库
仓库将建立在一个名为 Library 的数据库中。DWC 通过 ODBC 与仓库数据库进行通信,因此一定要将仓库和控制数据注册为支持 ODBC 访问的数据库。
定义仓库源
Library 仓库的所有源数据都来自从 Excel 电子表格中提取的逗号分隔文件(参见
附录 A 中的示例数据)。DWC 从这些文件导入数据之前,这些文件必须被定义成仓库源。支持的源类型有多种,这里选择本地文本文件作为每个表的源。定义所有的源之后,DWC Sources 将如下所示:
图 8. 仓库源文件
定义仓库目标
仓库目标通常是仓库中包含维(dimension)和实际数据的表,该例中要定义与每个源文件匹配的表。
图 9. 仓库目标表
定义仓库过程
现在已经定义了源和目标,还需要一种将其连接起来的方法。该例中使用 9 个不同的过程,每个过程都讲一个文本文件映射到相应的 DB2 表。这些过程是按照 DWC 中的 Subject Areas 组织的。首先创建一个 Subject Area (Library)。这样将在 Library 下自动创建一个 Processes 文件夹。右击 Processes 文件夹创建需要的 9 个过程。一定要将您的组移动到每个定义适当的 Security 选项卡中。现在创建的仅仅是占位符,以后还要添加源、目标和操作。Author 数据的 Process and Security 选项卡应该如下图所示:
图 10. 定义仓库过程
图 11. 定义仓库过程的安全性
定义所有的过程之后,DWC 树看起来将如下所示:
图 12. 仓库过程
向过程中添加数据源和目标
DWC 支持用图像化的方式构建过程。因为要创建 9 个类似的过程,这里只讨论开发 Author 过程的步骤。其他过程的开发都与此类似。
在 Processes 树中,双击 Build Author Dimension 项打开图形化界面,在这里可以规定源、目标、操作和数据路径。这项操作要用到三个图标:
图 13. 过程定义图标
首先选择 Sources and Targets 图标,然后再次单击希望出现的位置。从弹出的窗口的 Warehouse Sources 树上选择文件,对目标表(Author)重复这个过程。
在 Define Processes 图标中依次选择 DB2 UDB 、Load。
这就定义了一个 DB2 LOAD 过程,然后通过 Data Paths 将其连接到源表和目标表。选中 Data Paths 图标并选择 Data Link 弹出菜单,鼠标指针变成一个下箭头,单击 Source File,并将其拖动到 Load Process 中。然后重复这个操作,再将其从 Load Process 拖动到 Target Table 。保存过程前,一定要将 Properties 窗口中的 Load Mode 从 INSERT 改为 REPLACE。这样就可以定期更新数据,而不需要成批管理它们(因为数据量很少,可以每周重新加载一次,而不必执行递增更新)。
画面如下图所示:
图 14. 过程定义
测试仓库步骤
右击 Load Process,并将 Mode 从 Development 改为 Test。注意,过程和目标表上现在都出现了一把锁。如果右击目标表请求显示示例内容,就会看到一个空的窗口(因为还没有填充表)。
计划仓库过程
右击 Load Process 选择 Schedule。选择以后 5 分钟和每周一次(这样将自动进行更新)。然后再次右击该过程,并将 Mode 从 Test 改为 Production。要检查构建的状态,请选择 DWC 的主菜单,并从中选择 Warehouse --> Work in Progress。
一旦过程开始运行,会弹出一条警告信息,因为第一行数据被拒绝了。这是预期的结果,因为第一行包含列名而不是包含数据。
对其他数据集重复上述步骤。计划并运行所有的过程之后,Work in Progress 的窗口将如下图所示:
图 15. 计划好的过程
DB2 Information Integrator
有关的更多信息,请参阅
DB2 Information Integrator 8.2 主页。
DB2 Information Integrator V8.2 是 IBM 信息集成中间件的新版本,它可以帮助企业实现按需提供业务。它提供了业务集成和业务智能应用程序所需要的核心功能,其中包括访问不同的分布式数据,无论数据在何处,它们都像是一个单一的数据源。
DB2 Information Integrator (DB2 II) 提供了大量集成技术以满足不同的集成需求 —— 企业搜索、数据联邦、数据复制、数据转换和数据事件发布。DB2 II 技术建立在通用平台的基础上,很容易和业内领先的分析工具、门户环境、应用程序开发环境、消息中间件以及业务过程软件集成在一起。管理员更容易分发、巩固和同步信息,以促进应用程序集成、维护数据仓库、支持业务连续性,以及推动跨越复杂的多平台、多厂商 IT 环境的业务过程。
具备的功能、提供的工具以及管理的简单性都可以帮助组织加快新应用程序的推出,增加现有资产的收益,控制 IT 成本。
下图显示了 DB2 Information Integrator 中现在可用的过程和资源类型。
图 16. DB2 Information Integrator
特定的 ETL 任务可以使用数据联邦和数据复制技术。
数据联邦(Data Federation)
DB2 Information Integrator (DB2 II) 联邦功能使应用程序能够访问和集成不同的数据,无论分布式的、基于主机的、结构化的,还是非结构化的、公共的、私有的,不论这些数据实际上位于何处,它们仿佛在单一的数据源中。企业可以加快把新应用程序推向市场的时间,从原有的资产获得更多的价值,从而进一步控制 IT 成本。
联邦为业务职能和业务集成项目提供了广泛的功能。DB2 II 客户将该产品用于以下方面:
- 扩展原有的数据仓库。企业用户可以访问实时数据、非结构化内容或者远程数据,通过原有的数据仓库和数据集市与历史遗留信息实现无缝集成。DB2 II 提升了仓库投资的价值,使查询能够透明地跨越仓库、数据集市、生产系统、内容存储和 Web 等。DB2 II 可以开箱即用地使用领先的分析工具。
- 支持快速开发原型。DB2 II 帮助组织开发原型,使用联邦视图交互式地精化需求和测试新的报表或数据集市。经过验证之后,就可以适当地分阶段实施数据集市实现或者仓库扩展。
- 有利于开发跨越不同部门的报表。DB2 II 让企业使用标准报告工具建立跨越部门数据库、仓库或者市场的新报表,提供财务、库存、供应或其他重要资源的企业视图。它还可以作为数据合并或信息获取的临时解决方案,或者用于构建战略性解决方案。
- 提供企业范围的客户或产品视图。无论是构建客户或产品主数据库,还是扩展新的属性,DB2 II 都可以帮助您创建和提供客户和产品的全盘视图。
- 促进业务性能管理。高效响应业务事件意味着手头上拥有所有的数据 —— 从事件数据本身到相关的实时信息,再到数据仓库的历史性视图。DB2 II 为不同的资源提供了统一访问方式,其中包括数据库、过程监控器、应用程序、消息、电子表格和数据仓库,它们都使用单一的 SQL 查询,分析起来快捷简便。
- 简化和丰富了门户部署。从本质上讲,门户就是进入多个应用程序和数据领域的窗口。DB2 II 帮助开发人员更有效地访问和集成不同的、分散的数据,可以将手工编写的代码和开发时间减少一半。此外,它与标准的门户以及应用程序开发基础设施(如 portlet)兼容,从而最大程度地重用原来的工具和技能。通过内置的预建 Web 组件,它加速了以内容为中心的应用程序的部署,减少了与底层内容资源以及工作流系统的定制集成的需要。
数据复制
DB2 Information Integrator (DB2 II) 提供了快速、灵活的复制机制,帮助管理员在复杂的、多平台、多厂商 IT 环境中分发、加强和同步信息。复制可以在不同的上下文中应用:
- 促进应用程序集成。无论需要点到点、分布式还是联合拓扑,DB2 Information Integrator 都很容易管理不同应用程序域间的数据一致性。比如,零售商可以将订单从产品销售点复制到产品服务器,或者将最新的库存信息从产品服务器复制到销售商店系统。
- 维护数据仓库。DB2 II 可以帮助您利用最新的信息。它可以从事务数据库中捕获数据库的变动,并将其复制到操作型数据存储、数据仓库或者数据集市,以利用实时的业务智能。
- 支持业务连续性。DB2 II 可以通过独立或者交互的方式保持本地或远程备份系统的同步。
新的基于队列的 IBM 复制体系结构降低了时间延迟,提供了具备冲突检测和解决能力的高吞吐量的复制。从日志中捕获更改,并将它们存放到 WebSphere® 消息队列中。应用过程从队列中检索更改情况,并以并行的方式将它们应用到目标系统。Q Replication 是为支持业务连续性、工作量分配和应用程序集成情况而设计的。
对于不同厂商数据库之间的复制,DB2 Information Integrator 使用 IBM 基于 SQL 的复制体系结构,为管理计划安排、转换和分布拓扑提供了最大的灵活性和效能。在 SQL 复制中,DB2 II 使用基于日志的或者基于触发器的机制捕获变动情况,并将其插入到关系中间表(staging table)中。应用过程异步地处理目标系统的更新。DB2 II 被广泛地用于填充数据仓库或市场、维护不同应用程序间的数据一致性、高效地管理总部和分支机构或者零售机构之间的分发和合并场景。
数据可以在不同的关系数据源之间复制。
- 支持 DB2、Informix Dynamic Server、Microsoft® SQL Server、Oracle、Sybase SQL Server 和 Sybase Adaptive Server Enterprises 作为复制源或者目标。
- 支持 Informix Extended Parallel Server 和 Teradata 作为复制目标。
DB2 UDB 中的 WebSphere MQ 集成
关于 WebSphere MQ Series® 的更多信息,请参阅
WebSphere MQ 主页。
WebSphere MQ 消息产品可以帮助企业应用程序跨越不同的平台交换信息,将数据作为消息来发送和接收,从而促进了应用程序的集成。WebSphere MQ V5.3 目前支持的平台有 Linux for Intel、Linux for zSeries®、iSeries™ 和 Microsoft Windows XP。它们负责处理网络接口,保证“一次且只传递一次”消息,处理通信协议,在不同资源之间动态分配工作负荷,系统出现问题之后自动恢复,提高程序的可移植性。因此,程序员可以使用自己的技能解决关键的业务需求,而不必为底层网络的复杂性而困扰。
5.3 版的改进包括:
- 使用 Internet 安全通信标准 Secure Sockets Layer(安全套接字层,SSL) 增加了安全性。
- 增强了性能特性,特别是对 Java™ Message Service (JMS) 应用程序,可以选择 WebSphere MQ 作为 JMS 提供程序。
- 增加的其他特性,改进了系统的可伸缩性和可靠性,特别适用于能够分享负荷的系统集群。
- 程序员使用原来的 API 监控或者实现本地标准更简单了。
- WebSphere MQ 5.3 保持和上一版本 IBM MQSeries 5.2 的兼容性。
- 所有 WebSphere MQ Version 5 Release 3 产品都是 Euro 兼容的,AIX®、HP-UX、Sun Solaris 和 Windows 版本都适用于 Tivoli® 产品。
- WebSphere MQ 消息构成了 WebSphere Software Platform 的关键业务集成层。
WebSphere MQ 为多种平台、应用程序编程提供了一致的接口。其中的关键因素之一是与时间无关的处理方式。这意味着即使一个或多个接收方暂时联系不上,消息也能得到及时地处理。
Version 5 Release 3 使用安全套接字层增加了安全性,SSL 是安全通信的 Internet 标准。Version 5 Release 3 在性能上也有所改进,特别是对 JMS 应用程序,它允许将 WebSphere MQ 作为 JMS 提供程序。增加的其他特性改进了系统的可伸缩性和可靠性,特别适用于能够分享负荷的系统集群。程序员使用原来的 API 监控或者实现本地标准更简单了。WebSphere MQ 5.3 保持和上一版本 IBM MQSeries 5.2 的兼容性。所有 WebSphere MQ Version 5 Release 3 产品都是 Euro 兼容的,AIX®、HP-UX、Sun Solaris 和 Windows 版本都适用于 Tivoli® 产品。WebSphere MQ 消息构成了 WebSphere Software Platform 的关键业务集成层。
图 17. WebSphere MQ Integration for DB2 UDB
ETL 的 SQL 方法
前面已经介绍了 IMPORT DB2 命令如何使用 SQL 向表中插入数据。下面将介绍可以使用 SQL 执行 ETL 过程的不同部分的其他方法。
MERGE
MERGE SQL 语句使用源(表引用的结果)中的数据更新目标(一个表或者视图,如果底层表或视图的完全选择)。可以按照规定删除或者更新目标中与源匹配的行,还可以插入目标中不存在的行。在视图上更新、删除或插入一行之后,将在组成视图的表中更新、删除和插入行。
虽然这听起来似乎只能用于性质相同的表,但是 DB2 Information Integrator 新增的功能允许通过为不同数据源提供别名,将这些数据合并成接收系统上的一个表。一旦建立了别名,这些表对于 DB2 就像是本地系统的表,任何特殊的 SQL 或者其他问题都在 II 基础设施中解决。MERGE 语句的语法如下。
图 18. MERGE 语句
UNION ALL VIEW
关于使用 UNION ALL 连接数据的详细信息,请参阅白皮书
DB2 通用数据库版本 8 中可更新的 UNION ALL 视图。
基于 UNION ALL 的视图从 DB2 Version 2 开始受到支持。之后,这种视图就变得非常普遍。UNION ALL 视图的多数用法可以归为以下几类:
-
统一不同但语义上相关的表。这种构造在面向对象的层次结构和数据水平划分的关系映射中很常见,即每个“类”用一个表表示。典型的例子如由人员、雇员和管理人员组成的类层次结构,其中的人员、雇员和管理人员都是单独的关系表。要创建关于所有人的视图,可以使用 UNION ALL 视图统一这些表。
-
统一类似的表。用于类似表的 UNION ALL 构造常用于隐藏整个数据集的不同划分。每个划分都是一个单独的表,可以简化对这些表的维护、增加其容量、有时候还可以改善对全部数据的查询性能。典型的例子是将一年的销售额数据划分成 4 个表,每个表保存一个季度的数据。
-
联邦数据资源的集成。有时候必须将本地和远程数据库中的数据统一起来,这种情况下可以选择 UNION ALL 来获得所有数据的透明视图,而不必将数据复制到本地。
使用存储过程和用户定义函数进行转换
请下载
DB2 SQL Reference (Volume 2) 手册
,了解关于创建存储过程(CREATE PROCEDURE)、函数(CREATE FUNCTION)和触发器(CREATE TRIGGER)的信息。
过程和函数用于在存放到表中之前修改提取的数据。用函数将数字字符串转化成整数值就是一个简单的例子。虽然 IMPORT 和 LOAD 命令(通过规定目标列的类型)也提供了这种类型的功能,但有时候可能需要特殊处理。
过程和函数也可用于数据验证和净化。很多时候,一个简单的范围检查就能确定不正确的记录,并拒绝导入它们。然后可以改正被拒绝的记录,并重新读入这些记录。
转化和净化的另一种方法要用到带有过程或函数的触发器。只要对一列的 INSERT 方法启用触发器,该触发器就可以调用转换或净化过程,按照需要修改数据。比方说,如果导入的记录来自不同的数据源,那么每种数据源支持不同的日期格式。触发器调用的过程就可以检查日期格式,并调用 CASE 子句处理这些不同的格式,然后返回一致的日期存放到表中。虽然传统上函数只能返回单个值,但特定条件下 DB2 函数也可以返回行和/或表。这样就提供了一种成熟的方式,可以同时重新安排将数据输入到一行或者一个表中。
准实时 DB2 数据仓库
关于准实时数据仓库的更多信息,请下载
Preparing for Near-Realtime Business Intelligence 红皮书
。
提取、转换和加载是用于构建数据仓库的传统方式。但是要求更快、更加实时化的仓库更新(准实时业务智能),有助于定义执行批处理之外的更新所需的函数。虽然本文主要讨论的是 ETL,但如果您对准实时业务智能感兴趣,可以阅读 IBM 红皮书“Preparing for DB2 Near-Real-time Business Intelligence”。其中 3.5 章“关于 CDTA (捕获、传递、转换、应用)”指出了准实时数据更新需要考虑的新问题。
图 19. 准实时业务智能
DB2 数据移动工具
有关的更多信息,请参阅
DB2 Data Movement Utilities Guide and Reference Manual(第 6 章)
从一个 DB2 数据库到另一个数据库的数据移动可能占了填充大型数据存储任务的主要部分。下面几小节说明从 DB2 环境获取数据的不同方法。
使用 DB2 Connect 移动数据
如果您有一个复杂的系统,需要在主机数据库系统与工作站之间移动数据,那么可以使用 DB2 Connect,它是主机与工作站之间数据传输的网关。
DB2 EXPORT 和 IMPORT 工具允许从主机或 iSeries 服务器数据库将数据移动到 DB2 Connect 工作站上的文件中,或者相反。然后可以使用任何其他支持这种导出/导入格式的应用程序或者关系数据库管理系统。比如,您可以将主机或者 iSeries 服务器数据库上的数据导出为 PC/IXF 文件,然后再导入 DB2 for Windows 数据库。
db2move —— 数据库移动工具
db2move 工具简化了工作站 DB2 数据库之间大量表的移动。该工具查询特定数据库的系统目录表,编制出所有用户表的清单,然后将这些表导出为 PC/IXF 格式。这些 PC/IXF 文件可以导入或加载到同一系统的另一个本地 DB2 数据库,也可以传输到另一个工作站平台并导入或加载到该平台上的 DB2 数据库中。注意:使用该工具时,带有结构化类型列的表是不能移动的。
db2relocatedb —— 重定位数据库
db2relocatedb 工具用于按照用户给出的配置文件重命名数据库、重定位数据库或者数据库的一部分(比如容器或者日至目录)。该工具对 DB2 实例和数据库支持文件进行必要的修改。
db2 EXPORT 和 IMPORT —— 导出和导入
DB2 EXPORT 和 IMPORT 工具可用于移出、移入类型化表。类型化表可以是层次型的,层次间的数据移动可能包括:
- 从一个层次结构移动到相同的层次结构中。
- 从一个层次结构移动到另一个更大层次结构的一部分。
- 从一个大型层次结构的一部分移动成为单独的层次结构。
IMPORT CREATE 选项允许您同时创建表层次结构和类型层次结构。
层次结构中的类型确定由数据库决定。这意味着在不同的数据库中,同一类型具有不同的标识符。因此,在这些数据库之间移动数据时,相同类型的映射必须保证数据正确地移动。
导出操作过程中,将写出每个类型化的行,标识符被转化成一个索引值。该索引值可以是任何数字,从 1 到层次结构中相关类型的个数。索引值通过在以特殊顺序在层次结构中移动每种数据类型时编号来产生。这个顺序称为遍历顺序,即按照层次结构中从上到下、从左到右的顺序遍历上级表和子表。在表的层次结构之间移动数据时,顺序很重要,它决定了数据要移动的相对位置。
一种方法是从层次结构的最高层(即根表)开始,延层次结构向下移动到最低层,然后回到它的上级表,再向下移动到下一个“最右侧的”子表,最后回到次高的上级表,向下遍历其子表,依此类推。
使用复制来移动数据
复制功能允许定期将数据复制到多个远程数据库。如果需要自动将主数据库的更新复制到其他数据库,可以使用 DB2 的复制特性规定复制什么样的数据,多长时间复制一次更新。DB2 中的复制特性是小型和大型企业中更大的 IBM 数据复制解决方案的一部分。
IBM Replication 工具是一组 DB2 DataPropagator 程序和 DB2 Universal Database 工具,用来在分布式关系数据库管理系统之间复制数据:
- DB2 Universal Database 平台之间。
- DB2 Universal Database 与支持 Distributed Relational Database Architecture (DRDA) 连接性的宿主数据库之间。
- 支持 DRDA 连接性的宿主数据库之间。
通过 DB2 DataJoiner 也可以将数据复制到非 IBM 关系数据库管理系统中。
可以使用 IBM Replication 工具从单个控制点定义、同步、自动化和管理整个企业数据的复制操作。DB2 Universal Database 中的复制工具提供了关系数据库之间的复制。与 IMS DataPropagator(原来的 DPropNR)集合之后,该工具可以复制 IMS 和 VSAM 数据,而与 Lotus NotesPump 相结合,该工具可以复制 Lotus Notes 数据库中的数据。
通过复制可以让用户和应用程序访问产品数据,同时又不增加产品数据库的负担。可以将数据复制到用户或应用程序本地的数据库,而不必让其远程访问数据。典型的数据复制应用包括将一个源数据表复制到一个或多个远程数据库,比如中央银行及其地方机构。在预先规定的时间,自动更新 DB2 数据库,源数据库的所有变动都被复制到目标数据库表中。
复制工具允许定制复制表的结构。复制到目标数据库时,您可以使用更改过后的复制数据。您可以生成和源表相同的只读副本,在特定的时间点捕获数据,提供更改后的历史信息,或者对复制到新表中的数据预演。此外,您还可以创建读写的版本,使终端用户或应用程序能够更新它,然后将更改后的数据复制到原来的主表。可以复制原表的视图或者副本的视图。该工具还支持事件驱动的复制。
您可以在 DB2 数据库和下列平台间复制数据:AIX、AS/400®、HP-UX、Linux、Windows、OS/390、SCO UnixWare、Solaris Operating Environment、Sequent、VM 和 VSE 等。也可以在 DB2 和下列非 DB2 数据库之间复制数据(通过 DB2 DataJoiner):Informix、Microsoft Jet、Microsoft SQL Server、Oracle、Sybase 和 Sybase SQLAnywhere 等。与其他 IBM 产品相结合,您可以在 DB2 和 IMS、VSAM 或 Lotus Notes 之间复制数据。最后,还可以将数据复制到 Windows CE 或者 Palm OS 设备上的 DB2 Everywhere。
使用 Data Warehouse Center 移动数据
可以使用 Data Warehouse Center (DWC) 把数据从操作性数据库移动到仓库数据库,用户可以查询仓库,得到决策支持。也可以使用 DWC 定义操作性数据库的称为源的结构。然后规定如何将操作性数据移动和转换到仓库中。可以对仓库数据库中称为目标的表结构进行建模,或者作为数据移动操作定义过程的一部分自动移动数据。
Data Warehouse Center 使用以下 DB2 功能移动和转化数据:
- SQL —— 可以使用 SQL 从源表中选择数据和向目标表中插入数据。也可以使用 SQL 将数据转化成仓库格式。还可以使用 Data Warehouse Center 生成 SQL,或者编写自己的 SQL。
- 加载和导出工具 —— 可以使用这些 DB2 工具从源表中导出数据,然后将它们加载到目标中。如果需要移动大量数据,这些工具非常有用。Data Warehouse Center 支持下列加载和导出操作类型:
- DB2 数据导出 —— 从本地 DB2 数据库将数据导出到带分隔符的文件中。
- ODBC 数据导出 —— 从注册到 ODBC 的数据库中选择表的数据,然后将数据写入带分隔符的文件中。
- DB2 加载 —— 从分隔符文件中将数据加载到 DB2 表中。
- DB2 加载到 DB2 UDB ESE 数据库(仅用于 AIX)——从分隔符文件中将数据加载到 DB2 Universal Database Enterprise Server Edition 数据库,用新的数据代替原来的数据。该操作获得数据库的目标分区映射,对数据文件分区,因此每个文件都可以加载到一个数据库分区中,然后在所有分区上运行远程加载操作。
- Replication —— 可以使用复制功能将大量数据从仓库源复制到仓库目标,然后捕获元数据的所有变化。Data Warehouse Center 支持以下类型的复制:
- Base aggregate —— 创建一个目标表,包含用户表的聚合数据,按照指定的间隔追加。
- Change aggregate —— 创建一个目标表,包含聚合后的数据,这些数据以源表记录的变动为基础。
- Point-in-time —— 创建一个与源表匹配的目标表,并在目标表中增加时间标签列。
- Staging table —— 创建一个“consistent-change-data”表,作为多个目标表的更新数据源。
- User copy —— 在复制时创建与源表匹配的目标表。
所有 DB2 Universal Database 工作站操作环境、DB2 Universal Database for OS/390、DB2 for AS/400 和 DataJoiner 都支持这些操作。
- 转换器存储过程——可以使用 Data Warehouse Center 将数据移动到 OLAP(联机分析处理)数据库中。数据进入仓库后,可以使用转换器存储过程净化数据,然后将这些数据聚集到事实表和维表中。也可以使用转换器生成统计数据。一旦数据被净化和转换,就可以将其加载到 OLAP 立方体中,或者复制到部门服务器(有时候称为数据集市)。转换器只有某些 DB2 产品提供。
使用游标文件类型移动数据
使用 LOAD 命令时指定 CURSOR 文件类型,您可以将 SQL 查询的结果直接加载到目标表中,而不需要创建中间导出文件。通过参考 SQL 查询中的别名,加载工具也可以直接从另一个数据库中加载数据。
要从 CLP 中的游标操作执行加载,必须首先为 SQL 查询声明一个游标。然后就可以使用声明的游标名称作为 cursorname,CURSOR 作为文件类型发出 LOAD 命令。
比如:
表 ABC.TABLE1 中有 3 列:
- ONE INT
- TWO CHAR(10)
- THREE DATE
表 ABC.TABLE2 中有 3 列:
- ONE VARCHAR
- TWO INT
- THREE DATE
执行下面的 CLP 命令,将 ABC.TABLE1 中的所有数据加载到 ABC.TABLE2 中:
DECLARE mycurs CURSOR FOR SELECT TWO,ONE,THREE FROM abc.table1 LOAD FROM mycurs OF cursor INSERT INTO abc.table2
|
第三方 ETL 厂商
下列厂商也提供了一些有用的 ETL 工具,同时给出了相应的厂商网站链接。
DB2 ETL 的未来
关于 DB2 ETL 产品的更新,请参阅
DB2 Universal Database Data Warehouse Edition 主页。
需求
为了满足日渐增长的对 ETL 功能的需求,IBM 正努力为 Business Intelligence 和 Information Integration 实现无缝集成的、可伸缩的 ETL 功能:
- 灵活的体系结构,以满足当前和将来的需求,利用 IBM Software Group 基础设施(DB2、Eclipse、Rational、WebSphere)。
- 功能上与 Oracle Warehouse Builder 和 Microsoft 的 Integration Services 匹敌,改善现在的 DB2 Data Warehouse Center 和 Warehouse Manager。
- 易于配置和使用。
- 通过元数据交换和公开 ETL 运算子,得到强大的用户支持。
- 广泛的平台支持,与 DB2 UDB for Linux、 Unix 和 Windows 相匹配。
方法
DB2 的下一代 ETL 功能将以可扩展的、基于组件的体系结构为基础。无论部署在传统的数据仓库、实时仓库中,还是部署在企业信息集成场景中,新的转换功能都具有以下特征:
- 基于 DB2 SQL 的转换引擎和语言。
- 简单易用。
- 与 IBM Software Group (SWG) Service Oriented Architecture 集成在一起。
- 利用来自世界一流的 SWG 技术的共享子组件,其中包括 Rational Data Architect、Eclipse、WebSphere Process Choreographer、Integrated Solution Console、DB2 Information Integrator 等。
- 对合作伙伴公开的、可扩展的体系结构。
- 定制的 ETL 运算子接口,保护客户对遗留 SQL 的投资。
- 与其他 DB2 Data Warehouse Edition 分析工具集成,以便实现 OLAP、数据挖掘、报告、共享的设计和管理 GUI、共享的数据等。
这种方法将造就高度集成的 ETL 系统,突出数据的内在转换、端到端的 BI 和 EII 流。下图显示了这种方法的某种部署环境。
图 20. 下一代 DB2 ETL
结束语
本文介绍了为大型资料库提取、转换和加载数据的不同方法。有的方法易于实现和执行,但是缺乏 IBM 和其他 ETL 厂商的高端工具所具备的复杂转换和净化功能。ETL 成功的关键在于选择最适合需要的过程,没有不需要的特性和开销造成的“过度投资”。
附录 A: 示例数据仓库
图 21. Library 数据库布局
创建 Library 数据库的 SQL 命令
CONNECT TO Library;
DROP TABLE Volume;
CREATE TABLE Volume
(
Volume_No SMALLINT UNIQUE NOT NULL,
Volume_Type_No SMALLINT,
Volume_Title_No SMALLINT,
Volume_Publisher_No SMALLINT,
Volume_Publish_Date SMALLINT,
Volume_Media_No SMALLINT,
Comment VARCHAR(255)
);
DROP TABLE Story;
CREATE TABLE Story
(
Story_No SMALLINT NOT NULL,
Author_No SMALLINT,
Story_Type_No SMALLINT,
Story_Title_No SMALLINT,
Volume_Title_No SMALLINT,
Copyright_Date SMALLINT,
Comment VARCHAR(255)
);
DROP TABLE Volume_Title;
CREATE TABLE Volume_Title
(
Volume_Title_No SMALLINT NOT NULL,
Volume_Title VARCHAR(255),
Comment VARCHAR(255)
);
DROP TABLE Volume_Type;
CREATE TABLE Volume_Type
(
Volume_Type_No SMALLINT NOT NULL,
Volume_Type CHAR(32),
Comment VARCHAR(255)
);
INSERT INTO Volume_Type
VALUES
(0, 'Book', NULL),
(1, 'Collection', NULL),
(2, 'Video', NULL),
(3, 'Audio', NULL);
DROP TABLE Volume_Publisher;
CREATE TABLE Volume_Publisher
(
Volume_Publisher_No SMALLINT NOT NULL,
Volume_Publisher_Name VARCHAR (128),
Volume_Publisher_Country CHAR(32),
Comment VARCHAR(255)
);
DROP TABLE Volume_Media;
CREATE TABLE Volume_Media
(
Volume_Media_No SMALLINT NOT NULL,
Volume_Media CHAR(32),
Comment VARCHAR(255)
);
INSERT INTO Volume_Media
VALUES
(0, 'Hardback', NULL),
(1, 'Paperback', NULL),
(2, 'VHS', NULL),
(3, 'DVD', NULL),
(4, 'Audio Tape', NULL);
DROP TABLE Author;
CREATE TABLE Author
(
Author_No SMALLINT NOT NULL,
Author VARCHAR(128),
Comment VARCHAR(255)
);
DROP TABLE Story_Type;
CREATE TABLE Story_Type
(
Story_Type_No SMALLINT NOT NULL,
Story_Type CHAR(32),
Comment VARCHAR(255)
);
INSERT INTO Story_Type
VALUES
(0, 'Novel', NULL),
(1, 'Short Story', NULL),
(2, 'Play', NULL),
(3, 'Movie', NULL),
(4, 'TV Movie', NULL),
(5, 'Biography', NULL),
(6, 'Auto-Biography', NULL),
(7, 'Reference', NULL),
(8, 'Essay', NULL);
DROP TABLE Story_Title;
CREATE TABLE Story_Title
(
Story_Title_No SMALLINT NOT NULL,
Story_Title VARCHAR(255),
Comment VARCHAR(255)
);
TERMINATE;
|
注意,有些表已经填充了数据(因为这些数据是静态的,属于设计的一部分)。其他表包含“活动的”数据,可以通过 INSERT、IMPORT 或 LOAD 语句来填充这些表。原始数据的例子如下:
Story 表的数据
Story_No,Author_No,Story_Type_No,Story_Title_No,Volume_Title_No,Copyright_Date,Comment
1,1,0,1,1,2001,
2,1,0,2,2,1967,
3,1,0,3,3,1962,
4,1,0,4,3,1963,
5,1,0,5,3,1971,
6,1,0,6,4,1963,
7,1,0,7,5,1994,
8,1,0,8,6,1992,
9,1,0,2,7,1967,
10,1,0,14,7,1972,
(DATA TRUNCATED)
|
Story_Title 表的数据
Story_Title_No,Story_Title,Comment
1,Death in Holy Orders,
2,Unnatural Causes,
3,Cover Her Face,
4,A Mind to Murder,
5,Shroud For a Nightingale,
6,A Mind to Murder,
7,Original Sin,
8,The Children of Men,
9,Devices and Desires,
10,A Certain Justice,
(DATA TRUNCATED)
|
Volume 表的数据
Volume_No,Volume_Type_No,Volume_Title_No,Volume_Publisher_No,Volume_Publisher_Date,Volume_Media_No,Comment
1,0,1,1,2001,0,First American Edition
2,0,2,2,2001,1,
3,1,3,3,1987,0,
4,0,4,2,2001,1,
5,0,5,4,2002,1,
6,0,6,1,1993,0,
7,1,7,5,1980,0,
8,0,8,2,2003,0,
9,0,9,5,1980,0,
10,0,10,5,1982,0,
(DATA TRUNCATED)
|
Volume_Publisher 表的数据
Volume_Publisher_No,Volume_Publisher_Name,Volume_Publisher_Country,Comment
1,Random House,USA,Alfred A. Knopf
2,Simon and Shuster,USA,Scribner Paperback Fiction
3,Avenel Books,USA,Scribner Book Company
4,Warner Books,USA,AOL Company
5,Charles Scribner's Sons,USA,
6,Walker and Company,USA,
7,Harcourt,USA,
8,Bantam Books,USA,
9,Ballantine Books,USA,
10,Fontana,USA,
(DATA TRUNCATED)
|
Volume_Title 表的数据
Volume_Title_No,Volume_Title,Comment
1,Death in Holy Orders,
2,Unnatural Causes,
3,P. D. James Three Complete Novels,
4,A Mind to Murder,
5,Original Sin,
6,The Children of Men,
7,Murder in Triplicate,
8,The Murder Room,
9,Innocent Blood,
10,The Skull Beneath the Skin,
(DATA TRUNCATED)
|
Author 表的数据
Author_No,Author,Comment
1,P. D. James,
2,Dorothy L. Sayers,
3,Alzina Stone Dale,
4,Matthew Bunson,
5,Agatha Christie,
6,Kathleen Tynan,
7,Dick Riley and Pam McAllister,
8,Dawn B. Sova,
9,Dennis Sanders and Len Lovallo,
10,Tom Adams and Julian Symons,
(DATA TRUNCATED)
|
参考资料
关于作者  | 
|  | Dan Simchuk 在高级技术部门有三十多年的从业经验。他在 IBM 专门从事 DB2 和 Informix® 技术方面的工作已经有 9 年了,他是 Information Management Partner Enablement Group 的成员之一。 |
对本文的评价
|  |