IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Information Management  >

将 <emphasis>XML 数据</emphasis> 映射到 DB2 的另一种方式

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

João Alberto de O. Lima, 程序员/分析员

2002 年 6 月 01 日

DB2 脚本编制用于自动执行任务、测试和使简单场景快速成型。本文描述了如何编写包含了 SQL 程序元素的脚本、如何将脚本的输出转化为一个日志文件以及如何处理参数。

摘要

尽管 XML(可扩展标记语言)元语言问世不久,但对于电子商务世界,它已经被认为是一项关键性技术。每天以这种新格式交换信息的数量和对于集成现有数据的需求都在不断增长。为了满足这种需求,IBM 已创建了 XML Extender for DB2。基本上,XML Extender 提供了两种方法来将 XML 数据集成到 DB2:列方法和集合方法。本文介绍了一种不同于 DB2 XML Extender 所使用的方法。这里呈现的解决方案具有简单、高效和灵活等特点。它简单,因为它只使用三个表来映射 XML 数据。它高效,因为索引适合于最佳访问路径的选择。而且,它灵活,因为通过 SQL 语句,有可能对 XML 数据应用许多操作。在本文的标题中,对表达式“XML 数据”应用 emphasis是为了强调这个建议的解决方案只是应用于 以数据为中心的 XML 文档(而不是 以文档为中心的)。





回页首


简介

关系数据库管理系统(RDBMS)处理大量数据的能力是毫无疑问的。传统的应用程序将“结构化数据”存储在表中。可选地,定义索引来优化查询和保证唯一性。SQL 查询的优化利用了一些复杂的功能,例如:查询重写、多连接(join)方法、详细的统计、并行性等。RDBMS 的发展应归功于这样的事实,RDBMS 是基于 E.F.Codd [Codd1969] 正式定义的模型:关系模型。例如,这种理论模型允许用更有效的等价操作来代替关系代数操作同时不影响结果。RDBMS 优化器以自动方式来完成这种替代。

XML 标准的一个主要特性是:允许以一种一致的和比 SGML(标准通用标记语言)更简单的方式来对数据(通常是指“非结构化的”或“半结构化”的数据)进行操作。基本上,可以认为 XML 文档是“格式良好的”或“有效的”文档。一个“有效的” XML 可以包含一个 DTD(文档类型定义)或者引用一个 DTD,并且该文档符合这个 DTD。“格式良好的” XML 文档遵循 XML 标准的所有规则,但它可以没有 DTD,或者不遵守 DTD。

将 XML 数据映射到关系模型不是一件普通的任务(这也许就是市场上存在多种映射解决方案的原因之一)。

根据 Ronald Bourret [Bourret2001]

“XML 文档分为两大类:以数据为中心和以文档为中心。以数据为中心的文档是那些 XML 在其中被用作数据传输的文档。 这些文档包括销售订单、病人记录和科学数据。这些文档的物理结构 — 兄弟元素的次序、数据是存储在属性中还是在 PCDATA 元素中、是否使用实体 — 往往是不重要的。(……)以文档为中心的文档是那些 XML 在其中可以发挥象 SGML 那样作用的文档,譬如在用户手册、静态 Web 页面和市场宣传手册中等。这些文档的特征是:具有不规则的结构和混合的内容,而且,文档的物理结构是重要的。”

本文只讲述如何处理以数据为中心的文档。





回页首


XML 的基本概念

按照定义,XML 文档的结构是树状结构。只有一个根节点,所有其它节点都必须以分层形式来组织。在 清单 1中,我们介绍了一个 XML 文档示例。它的根节点是bibliography 元素。在第一行中,该文档声明这是一个 XML 文档,第二行表明将使用哪个 DTD 来验证该文档。 图 1清单 1 中 XML 文档的图形表示。DTD 定义了所有元素的次序和它们各自的属性(请参阅 清单 2)。例如:book 元素下包含 authors或author 元素,并且紧随其后的元素必须是元素 title、publisher和可选项地isbn 元素。重要的是注意:DTD 不包含带 MIXED 或 ANY 内容模型的元素。这是使得数据的映射和处理更方便的 XML 以数据为中心文档的特性之一。


<?xml version="1.0"?>
<!DOCTYPE bibliography SYSTEM "biblio.dtd">
<bibliography>
   <entry id="Date2000">
      <book year="2000" edition="2nd">
         <authors>
            <author>C. J. Date</author>
            <author>Hugh Darwen</author>
         </authors>
         <title>Foundation for Future Database Systems - The Third Manifesto</title>
         <publisher>Addison Wesley</publisher>
         <isbn>0-201-70928-7</isbn>
      </book>
   </entry>
   <entry id="Codd1970">
      <article year="1970">
         <author>E. F. Codd</author>
         <title>A Relational Model of Data for Large Shared Data Banks</title>
         <journal>Communications of ACM</journal>
         <volume>13</volume>
         <pages>377--387</pages>
         <issn>0001-0782</issn>
      </article>
   </entry>
</bibliography>

清单 1. XML 以数据为中心样本文档


<!ELEMENT bibliography ( entry )* >
<!ELEMENT entry        ( article | book ) >
<!ATTLIST entry
   id         ID         #REQUIRED >
<!ELEMENT article      (( author | authors ), title, journal, volume?, pages?, issn? ) >
<!ATTLIST article
   year       CDATA     #REQUIRED >
<!ELEMENT book         (( author | authors ), title, publisher, isbn? ) >
<!ATTLIST book
   year       CDATA    #REQUIRED 
   edition    CDATA    #IMPLIED >
<!ELEMENT authors      ( author  )*  >
<!ELEMENT author       ( #PCDATA )   >
<!ELEMENT title        ( #PCDATA )   >
<!ELEMENT journal      ( #PCDATA )   >
<!ELEMENT year         ( #PCDATA )   >
<!ELEMENT volume       ( #PCDATA )   >
<!ELEMENT pages        ( #PCDATA )   >
<!ELEMENT issn         ( #PCDATA )   >
<!ELEMENT publisher    ( #PCDATA )   >
<!ELEMENT isbn         ( #PCDATA )   >

清单 2. XML 以数据为中心样本文档的 DTD


XML 以数据为中心样本文档的图形表示

图 1. XML 以数据为中心样本文档的图形表示





回页首


表现和表示

本文解决了以下问题:如何在所有数据都是以表格形式 表现的关系数据库中 表示 XML 数据(它与生俱来就是一种层次结构)。强调表现和表示之间的差别,这是很重要的。在这个问题上,Chris Date [Date2000] 非常强调这一点:

“……我非常讨厌听到这样的说法,‘关系模型是二维的’,或者说关系是‘平面的’(等等),而实际数据是‘多维’的。很清楚,那些认为这些说法构成对关系模型的有效批评的人显然没有理解这种模型,事实上是完全不明白。当然,在纸上以表格形式绘制时,关系看上去确实是平面的。但图上画的与实际的是两码事!如果一个关系有 n 列,那么这个关系中的每行表示 n 维空间中的一点 — 而且这个关系作为一个整体代表了一组这样的点。换句话说,n 列的关系是 n 维的,而不是二维的!”

按照同一想法,我们想要指出,用关系模型来“表示”XML 的层次结构是可能的。使用 Joe Celko [Celko1995] 所建议的方法之一,下面将要表现的数据模型表示了这种树结构。





回页首


建议的数据模型:结构

这个建议的数据模型非常简单,它只由三个关系组成:Document — 表示每个 XML 文档实例的一个元组;Element — 表示 Document 的每个元素的一个元组;Attribute — 表示 Element 的每个属性的一个元组。 图 2 显示了这个建议的解决方案的实体-关系(Entity-Relationship)图。


建议的解决方案的实体-关系图

图 2.建议的解决方案的实体-关系图

Document表有以下属性:SEQ_XML— 用来标识 XML 文档实例(主键)的序列号;TEXT_XML — XML 文档的原始内容;HEAD_XML — 包含 XML 头的声明,有关于编码、版本等方面的信息;DTD_REF_XML — 包含对 DTD 文件的引用;WELL_FORMED — 表明 XML 文档是否是格式良好的;VALID_XML — 表明 XML 文档是否有效。

Element表有以下属性:SEQ_XML— 用来标识 XML 文档实例(主键和外键)的序列号;ORD_INITIAL — 由树遍历算法生成的数,该数标识了元素在树中的次序(在访问该元素的从属元素 之前);TAG_NAME — 元素名称;ORD_FINAL— 由树遍历算法生成的数,该数标识了元素在树中的次序(在访问该元素的从属元素 之后);TAG_CONTENT — 元素内容,如果它存在;QTD_ATTRIBUTE — 元素所具有属性的数目。

Attribute表有以下属性:SEQ_XML 和 ORD_INITIAL(外键和主键);ATT_SEQ — 标识属性顺序的序列号(主键);ATT_NAME — 属性名称;ATT_VALUE — 属性值。

表 Element和Attribute 将元素和属性内容作为 VARCHAR 列存储。该内容可以是数字、日期、字符串等,这取决于应用程序。建议的模型的表不应该被视为数据的最终目的地,而应视为“数据阶段”。在对分段文档进行解析、验证和存储之后,根据每个应用程序来检索数据项,然后将这些数据项发送到最终目的地,在那里会对这些数据项做一些常规处理。

要确保从一般 VARCHAR 列的内容到目标列的映射不会导致不一致,可以在解析/验证过程使用 XML Schema 标准中的一些资源。例如,假定在 XML 文档中存储了一个无效的日期(2001 年 2 月 30 日)。如果只有 DTD 验证,则不会检测出这个错误(该无效日期会存储在 VARCHAR 列中,并且只有在到 DATE 类型列的最终映射上,才能发现该错误)。有了 XML Schema,就会在解析/验证时检测出这个错误。

图 3 显示了带有每个元素有序编号的 XML 文档的图形表示。下图显示了每个元素拥有一对数字:左边那个数字代表 ORD_INITIAL,右边那个数字代表 ORD_FINAL。如果使用 DOM(文档对象模型),则对 XML 文档进行解析和验证(可选)之后,可以应用树遍历算法。值得注意的是:数学表达式 ((Element.ORD_FINAL - Element.ORD_INITIAL - 1) / 2) 表示该元素的从属元素的数目。

通过使用 XML 数据样本文档, 图 4 显示了我们所考虑的模式(schema)的一个实例。


有序编号

图 3. 带有序编号的 XML 以数据为中心样本文档的图形表示


XML 样本文档

图 4. XML 以数据为中心样本文档的表表示





回页首


建议的数据模型:操作

这个建议的模型允许完成许多类型的操作。在本文中,我们将看三个操作的组:

重构原始 XML

要重构原始 XML,必须创建一个利用 UNION ALL 操作符的 SELECT 语句。 清单 3 显示了该 SELECT 语句,它由 4 个子选择语句组成,如下所示:

  • 第一个 SELECT 语句返回主要内容:元素的初始标记、它的属性和内容;
  • 第二个 SELECT 语句返回元素的最后一个标记;
  • 第三个 SELECT 语句返回 XML 文档的标题行。
  • 而最后一个 SELECT 语句返回 DTD 这一行(如果它存在)。

最后,ORDER BY 根据最初的层次,将初始标记和最后一个标记放在适当的位置,处理结果的排序。


SELECT CASE WHEN COALESCE(att_seq, 1) = 1  
            THEN '<' || RTRIM(e.tag_name) 
            ELSE '' END  
    || CASE WHEN COALESCE(att_seq, 0) > 0 
            THEN ' ' || RTRIM(att_name) || '="' || RTRIM(att_value) || '"' 
            ELSE '' END  
    || CASE WHEN qtd_attribute = COALESCE(att_seq, 0) 
            THEN '>' 
            ELSE '' END 
    || COALESCE(RTRIM(tag_content), '') AS line, 
    e.ord_initial  AS ord, 
    att_seq        AS ord_att
FROM relxml.element   e
       LEFT OUTER JOIN
     relxml.attribute a
     ON  e.seq_xml     = a.seq_xml
     AND e.ord_initial = a.ord_initial
WHERE e.seq_xml = 
        0
UNION ALL
SELECT '</' || RTRIM(tag_name) || '>'  AS line, 
       ord_final AS ord, 
       0         AS ord_att
FROM relxml.element
WHERE seq_xml = 
        0
UNION ALL
SELECT RTRIM(head_xml)    AS line, -1 AS ord, 0 AS ord_att
FROM relxml.document
WHERE seq_xml = 
        0
UNION ALL
SELECT RTRIM(dtd_ref_xml) AS line,  0 AS ord, 0 AS ord_att
FROM relxml.document
WHERE seq_xml = 
        0
ORDER BY ord, ord_att
      

清单 3. 用“seq_xml = 0”重构 XML 文档

返回一个确定的子树也是可能的,在这种情形下,必须指出它的根元素。 清单 4显示了所需要的 SELECT 语句,该语句将从Book 元素(ord_initial = 3,ord_final = 16)返回期望的子树。请注意用 黑体表示的行,这些行起到了子树过滤器的作用。


SELECT CASE WHEN COALESCE(att_seq, 1) = 1  
            THEN '<' || RTRIM(e.tag_name) 
            ELSE '' END  
    || CASE WHEN COALESCE(att_seq, 0) > 0 
            THEN ' ' || RTRIM(att_name) || '="' || RTRIM(att_value) || '"' 
            ELSE '' END  
    || CASE WHEN qtd_attribute = COALESCE(att_seq, 0) 
            THEN '>' 
            ELSE '' END 
    || COALESCE(RTRIM(tag_content), '') AS line, 
    e.ord_initial  AS ord, 
    att_seq        AS ord_att
FROM relxml.element   e
       LEFT OUTER JOIN
     relxml.attribute a
     ON  e.seq_xml     = a.seq_xml
     AND e.ord_initial = a.ord_initial
WHERE e.seq_xml = 0
        AND   e.ord_initial >= 3  and e.ord_final <=  16
UNION ALL
SELECT '</' || rtrim(tag_name) || '>'  AS line, ord_final AS ord, 0 AS ord_att
FROM relxml.element
WHERE seq_xml = 0
        AND   ord_initial >= 3  and ord_final <=  16
ORDER BY ord, ord_att
      

清单 4. 从原始的 XML 文档重构子树。

在元素间导航

给定一个元素,根据该元素与目标元素之间关系的某些特征来导航至目标元素是可能的。在这一节中,用建议的解决方案来探索导航的某些可能性。我们将验证以下导航情况:

下表有两列:左边一列显示了操作、操作参数和实现该操作的 SELECT 语句;右边一列显示了说明导航的图。在图中,箭头将每次操作中的当前节点链接到那些要检索的节点。

              a) retrieve root node
Parameter: 
 1 - Document number (seq_xml)
SELECT tag_name
FROM   relxml.element 
WHERE  seq_xml = 
              0
AND    ord_initial = 1
              Result:
tag_name
------------
bibliography
              XPath Expression
            

检索根
              b) retrieve first child node
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 
SELECT tag_name, tag_content
FROM   relxml.element 
WHERE  seq_xml     = 
              0
AND    ord_initial = 
              4 + 1
              Result:
tag_name  tag_content
--------  -----------
author    C. J. Date
            

检索第一个子节点
              c) retrieve next sibling node 
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 
SELECT e2.tag_name, e2.tag_content
FROM relxml.element e, 
     relxml.element e2
WHERE e.seq_xml       = 
              0
AND   e.ord_initial   = 
              5
AND   e.seq_xml       = e2.seq_xml
AND   e.ord_final + 1 = e2.ord_initial
              Result:
tag_name  tag_content
--------  -----------
author    Hugh Darwen
            

检索下一个兄弟节点
              d) retrieve previous sibling node
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 
SELECT e2.tag_name, e2.tag_content
FROM relxml.element e, 
     relxml.element e2
WHERE e.seq_xml        = 
              0
AND   e.ord_initial    = 
              7
AND   e.seq_xml        = e2.seq_xml
AND   e2.ord_final + 1 = e.ord_initial
              Result:
tag_name  tag_content
--------  -----------
author    C. J.Date
            

检索上一个兄弟节点
              e) retrieve context;
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 3 - Final number    (ord_final)
 
SELECT e.tag_name, ord_initial
FROM relxml.element e 
WHERE e.seq_xml     = 
              0 
AND   e.ord_initial <= 
              7
AND   e.ord_final   >= 
              8
ORDER BY ord_initial DESC
              Result:
tag_name      ord_initial
------------  -----------
authors                 4
book                    3
entry                   2  
bibliography            1 
            

检索上下文
              f) retrieve parent node
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 3 - Final number    (ord_final)
SELECT e.tag_name, e.tag_content
FROM relxml.element e 
WHERE e.seq_xml = 
              0
AND   e.ord_initial < 
              7
AND   e.ord_final > 
              8
AND   e.ord_initial = 
   (SELECT MAX(ord_initial)
    FROM relxml.element e2
    WHERE e2.seq_xml = e.seq_xml
	AND e2.ord_initial < 
              7
	AND e2.ord_final > 
              8)
              Result:
tag_name      tag_content
------------  -----------
authors  
            

              g) retrieve last sibling node
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 3 - Final number    (ord_final)
SELECT e3.tag_name, e3.tag_content
FROM relxml.element e,
     relxml.element e3 
WHERE e.seq_xml       = 0
AND   e.seq_xml       = e3.seq_xml
AND   e.ord_final - 1 = e3.ord_final
AND   
              21 <> e3.ord_final 
AND   e.ord_initial < 
              20
AND   e.ord_final > 
              21
AND   e.ord_initial = 
   (SELECT MAX(ord_initial)
    FROM relxml.element e2
    WHERE e2.seq_xml = e.seq_xml
    AND   e2.ord_initial < 
              20
    AND   e2.ord_final > 
              21)
              Result:
tag_name      tag_content
------------  -----------
issn          0001-0782
            

检索最后一个兄弟节点
              h) retrieve first sibling node
Parameters:
 1 - Document number (seq_xml)
 2 - Initial number  (ord_initial)
 3 - Final number    (ord_final)
SELECT e3.tag_name, e3.tag_content
FROM relxml.element e,
     relxml.element e3 
WHERE e.seq_xml         = 0
AND   e.seq_xml         = e3.seq_xml
AND   e.ord_initial + 1 = e3.ord_initial
AND   
              30 <>  e3.ord_initial 
AND   e.ord_initial < 
              30
AND   e.ord_final > 
              31
AND   e.ord_initial = 
    (SELECT MAX(ord_initial)
     FROM relxml.element e2
     WHERE e2.seq_xml = e.seq_xml
     AND   e2.ord_initial < 
              30
     AND   e2.ord_final > 
              31)
              Result:
tag_name      tag_content
------------  -----------
author         E. F. Codd
            

检索第一个兄弟节点

表 1. 元素间的导航

注意:在该表中所显示的操作总是限定一个 XML 文档实例,即,总是提供 seq_xml 属性。优化器会选择 Element 表的主索引中的 Index Scan Matching(Matchcols = 2)访问路径,这将显著减少响应时间。

查询操作(元素和属性)

建议的模型允许通过简单的 SELECT 语句来查询某个元素或属性。下面显示了四种类型的查询:

在下表左边一列显示了操作类型、操作参数和相应的 SELECT 语句。在右边一列中显示了查询结果。

              a) retrieve elements based on 
an attribute's value.
Parameters:
 1 - Document number (seq_xml) 
 2 - Attribute name  (att_name)
 3 - Attribute value (att_value)
SELECT e.tag_name,  
       e.ord_initial, e.ord_final
FROM relxml.element   e,
     relxml.attribute a
WHERE e.seq_xml     = a.seq_xml
AND   e.ord_initial = a.ord_initial
AND   a.att_name    = 
              'year'
AND   a.att_value   = 
              '2000'
AND   e.seq_xml     = 
              0
            

              Result:
Tag_name ord_initial ord_final
-------- ----------- ---------
book               3        16
            

              b) retrieve elements based on 
an element's name.
Parameters:
 1 - Document number (seq_xml)
 2 - Element name   (tag_name)
SELECT tag_content, ord_initial, ord_final
FROM relxml.element 
WHERE  seq_xml   = 
              0
AND    tag_name  = 
              'author'
            

              Result:
Tag_content  ord_initial ord_final
-----------  ----------- ---------
J. C. Date             5         6
Hugh Darwen            7         8
E. F. Codd            20        21   
            

              c) retrieve elements based on 
an element's content.
Parameters:
 1 - Document number (seq_xml)
 2 - Element name    (tag_name)
 3 - Element content (tag_content)
SELECT ord_initial, ord_final
FROM relxml.element 
WHERE
      tag_name  = 
              'author'
and   tag_content = 
              'E. F. Codd'
and   seq_xml = 
              0
            

              Result:
ord_initial ord_final
----------- ---------
         20        21   
            

              d) retrieve leaf nodes.
Parameters:
1 - Document number (seq_xml)
SELECT ord_initial, ord_final,
       tag_name,    tag_content
FROM relxml.element 
WHERE
    seq_xml = 
              0
and ord_initial + 1 = ord_final
            

              Result:
o_i  o_f  tag_name  tag_content
---  ---  --------  ------------
  5    6  author    C. J. Date  
  7    8  author    Hugh Darwen 
 10   11  title     Foundation for Future ...  
 12   13  publisher Addisson Wesley 
 14   15  isbn      0-201-70928-7                  
 20   21  author    E. F. Codd                     
 22   23  title     A Relational Model of ... 
 24   25  journal   Communications of ACM
 26   27  volume    13                             
 28   29  pages     377--387                      
 30   31  issn      0001-0782                     
            

表 2. 元素和属性上的查询操作

在以上显示的这些示例中,总是提供了 XML 文档(seq_xml 属性)的实例。这意味着查询是在单个文档的元素/属性中执行的。然而,也有可能不通知实例,这时,查询将会应用于所有存储的文档 — 查询的作用域不再是树,而是森林。为了缩短这些查询的响应时间,必须创建一些索引:

  • 要优化查询“a”和“b”,必须在Attribute 表中列(att_name, att_value, seq_xml )上创建一个复合索引。
  • 要优化查询“c”,必须在 Element 表中列(tag_name, seq_xml)上创建一个复合索引。




回页首


限制

下面显示了这个建议的模型的一些限制:

  • 这个建议的解决方案不能应用于 MIXED 和 ANY 内容模型。在以文档为中心这一类的 XML 文档中,经常使用到这些内容模型。只要 DTD 不允许 MIXED 或 ANY 内容,这个建议的解决方案也可应用到以文档为中心的 XML 文档。
  • 更新 XML 文档的结构(包括或不包括节点)将需要对许多元素重新编号。对于那些具有许多元素和许多更新活动的文档,这种限制使得该解决方案不切实际。
  • 为了简化该模型,有意没有考虑 XML 所具有的某些特性,譬如:注释、CDATA 等。
  • 限制元素的名称最多可有 100 个字节,其内容最多可有 3000 个字节。可以修改这些限制。对于属性,则限制其名称和值各自最多有 255 个字节,这样可以使属性的名称和值加入到创建的复合索引中。由于可以索引属性的名称和内容,因此必须借助(在 DTD 的定义方面)作为属性(而不是元素)的数据项的建模,如果该数据项成为经常查询的参数的话。

Richard Edwards [Edwards2000] 和 Sian Hope 建议,对于 XML 文档到关系数据库的映射,在基于 DOM 的一般模型中不存在对 MIXED 和 ANY 内容模型的限制。它们的模式使用 15 张表,比我建议的要更完整和复杂。持久的 DOM 解决方案允许在关系数据库中存储任何类型的 XML 文档。





回页首


结束语

已经在 DB2 生产环境下成功地开发和测试了用于 DB2 的 XML 数据映射建议。该建议收集了两种技术的优点:XML 的灵活性和 DB2 的性能。电子商务解决方案有一个重要问题:可伸缩性。因此,将 RDBMS 的性能和全世界电子商务当前使用的语言 XML 结合在一起是很重要的。



参考资料



关于作者

照片:JoÃo Alberto de Oliveira Lima

照片:JoÃo Alberto de Oliveira Lima

JoÃo Alberto de Oliveira Lima 于 1991 年作为一名程序员/分析员开始了他的软件生涯。自从 1993 起,他作为一名开发人员、DBA 和 SQL 性能分析师一直从事 DB2 的工作。他拥有计算机科学专业的学士学位和软件工程专业的硕士学位。最近,他取得了下面一些证书:“DB2 UDB V7.1 Database Administration for OS/390”、“DB2 UDB V7.1 Database Administration for Unix, Windows and OS/2”和“DB2 UDB V7.1 Family Application Development”等方面的 IBM Certified Solutions Expert。他居住在巴西利亚(巴西),可以通过 joaolima@acm.org与他联系。

致谢:作者十分感谢 JoÃo Batista de Holanda Neto、Omar FalcÃo Soares、Ronald Bourret 和 Berthold Reinwald 对本文所提供的意见和建议。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款