| 了解 IBM® DB2® 9 for Linux®, UNIX®, and Windows® 新的 XML 存储和查询环境如何处理本系列 第 1 部分 中描述的 XML 数据模型。第 2 部分主要关注如何在应用程序体系结构中使用新的 XML 数据库支持。
简介
XML 在数据库中的地位在过去两年中已经发生了变化,从 “临时工” 变成了重要成员。它不再需要改变本身来适应关系环境。它可以保持其层次化性质,同时利用关系数据库环境的功能和稳定性。实际上,一些关系性元素已经采用某些技术让它们看起来像 XML,以便利用层次化 XML 模型丰富的功能。
本文讨论新的 XML 存储和查询环境如何处理本系列 第 1 部分 中的 XML 数据模型。还要说明,在采用新的基于 XML 的应用程序开发体系结构之后,数据库模式会变得更简单更自然。还演示如何按照在应用程序中查询数据的相同方式查询数据库中的 XML 数据。最后,讨论如何结合关系数据和 XML 数据,从而同时获得这两个环境的优势。
XML 数据库基础
尽管大多数主流关系数据库都有某种 XML 支持,但是 DB2 的 pureXML™ 支持要健壮和高效得多,这使它成为试验 XML 编程模型的理想数据库。本文主要关注如何在应用程序体系结构中使用新的 XML 数据库支持。
DB2 允许存储、查询、操作和发布:
- 关系数据 — SQL
- 采用 XML 形式的关系数据 — SQL/XML
- XML 数据 — XQuery
- 混合型数据(关系数据和 XML 数据) — SQL/XML 和 XQuery
图 1. DB2 混合型存储

在数据库中存储 XML
关系数据库中的 XML 支持的主要好处是,可以在同一个表中同时存储关系数据和 XML 数据。另外,尽管 XML 在内部存储为层次化(树)格式,但是它看起来像是存储在数据库表的单一列中(就像 CLOB 或 BLOB)。
从第 1 部分中的数据对象可以看出,有两个表,每个表至少有两列。
清单 1. 表
CREATE TABLE CUSTOMER_TABLE ( CUSTOMERID CHARACTER (12) NOT NULL, CUSTXML XML NOT NULL , CONSTRAINT CC1183665042494 PRIMARY KEY ( CUSTOMERID) )
CREATE TABLE PURCHASE_TABLE ( CUSTOMERID CHARACTER (12) NOT NULL , ITEMXML XML NOT NULL , CONSTRAINT CC1183665244645 FOREIGN KEY (CUSTOMERID) REFERENCES CUSTOMER_TABLE (CUSTOMERID) ON DELETE CASCADE ON UPDATE NO ACTION ENFORCED ENABLE QUERY OPTIMIZATION ) | 显然,通过将应用程序的数据对象存储为 XML,关系模式大大简化了。另外,基础结构仍然是关系型的,这使 XML 数据能够利用关系数据库的实用功能,比如触发器、约束和外键关系。
因为从逻辑上看 XML 列与 VARCHAR、CLOB 或 BLOB 列相似,所以 INSERT 语句也是相似的。
insert into CUSTOMER_TABLE values('hardeep',
'<Customer customerid="hardeep" firstname="hardeep" lastname="singh"/>') |
在 Java™ 程序中执行插入的代码也是相似的:
清单 2. 在 Java 程序中执行插入
String insertsql= "insert into PURCHASE_TABLE values(?,?)"; PreparedStatement iStmt=connection.prepareStatement(insertsql); File inputfile= new File(filename); //filename is the path of the XML file long filesize=inputfile.length(); BufferedReader in = new BufferedReader(new FileReader(inputfile)); iStmt.setCharacterStream(1,in,(int)filesize); int rc= iStmt.executeUpdate(); | 为了更好地了解混合型存储,我们来看看 XML 数据的逻辑视图,体会 XML 数据如何看起来像是存储在关系数据库表中。
注意:尽管不同关系数据库厂商的 XML 物理存储技术可能不一样,但是逻辑视图是相似的。
图 2. DB2 混合型存储逻辑视图

查询 XML
在展开数据库模式模型时,可以看到关系表和列。如果展开 XML 列,模式会从关系模型变成 XML 层次化模型。现在,您应该意识到其实有两个模式(一个关系模式和一个 XML 模式),但是把它们当作一个整体;理解了这一点,就能够以更自然的方式在这个统一的模式中进行导航和查询。
对于清单 1 所示的统一模式,如果希望获得 CUSTOMER_TABLE 中 CUSTXML 列的数据,那么可以在查询中指定 CUSTXML 列的路径作为目标。
SELECT CUSTXML FROM CUSTOMER_TABLE where customerid='hardeep'; |
这会返回 hardeep 的 CUSTXML 列中的客户数据。
现在,考虑如何获得其 lastname 为 singh 的客户数据。在这种情况下,需要指定每个 XML 文档的 lastname 属性的路径(CUSTOMER_TABLE.CUSTXML/Customer/@lastname)并检查它是否是 singh。
在完美的环境中,查询应该是 Select * from CUSTOMER_TABLE where CUSTXML/Customer/@lastname='singh'。但是在真实环境中,需要用数据库查询引擎能够理解的一种语法编写查询。数据库领域已经引入了一种称为 XQuery 的新语言,可以用它查询 XML 文档。SQL 添加了可以理解这种语言的新函数,从而将关系和 XML 环境联系起来了。所以搜索姓氏为 singh 的客户的查询如下:
select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$cust/Customer[@lastname= "singh" ]' passing CUSTXML AS "cust" ) |
还可以在 Java 程序中通过参数化查询执行这个调用:
select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$cust/Customer[@lastname= $lname ]'
passing CUSTXML AS "cust" , cast(? as VARCHAR(12)) as "lname") |
掌握了向 SQL/XML 函数传递参数的语法之后,您会发现,在针对关系数据和 XML 数据的基本混合型查询中,XML 查询通常包含 XPath 表达式。这与在应用程序层中操作 XML 数据模型的方法非常相似(见第 1 部分),在那里许多代码通过对 Document Object Model(DOM)包装器进行 XPath 调用来查询和操作 XML 数据。
注意:在 Viper 2 中,对传递给一些 SQL/XML 函数的参数做了简化。例如,在前面的查询中,XMLExists 的 passing 子句不需要指定 CUSTXML 列。
select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$CUSTXML/Customer[@lastname= $lname ]'
passing cast(? as VARCHAR(12)) as "lname")
|
将应用程序逻辑放在数据库中
XQuery 提供了大多数高级语言的所有基本功能(if-then-else、for、变量、函数和算术操作符)。因此,可以将业务逻辑嵌入查询中。另外,它还提供许多常用的 XSLT 映射,所以它不但能够执行查询,还能够在数据库中转换 XML 输出。
我们仍然以第 1 部分中 Customer 示例的 XML 数据模型为例。
<Customer customerid ="" firstname="" lastname="" >
<Items><Item ID="" description="" purchaseDate="" price="" /></Items>
</Customer>
|
[1] [2] [3] 下一页
|