简介
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 部分中的数据对象可以看出,有两个表,每个表至少有两列。
为了更好地了解混合型存储,我们来看看 XML 数据的逻辑视图,体会 XML 数据如何看起来像是存储在关系数据库表中。 注意:尽管不同关系数据库厂商的 XML 物理存储技术可能不一样,但是逻辑视图是相似的。
图 2. DB2 混合型存储逻辑视图
查询 XML
在展开数据库模式模型时,可以看到关系表和列。如果展开 XML 列,模式会从关系模型变成 XML 层次化模型。现在,您应该意识到其实有两个模式(一个关系模式和一个 XML 模式),但是把它们当作一个整体;理解了这一点,就能够以更自然的方式在这个统一的模式中进行导航和查询。
对于清单 1 所示的统一模式,如果希望获得 CUSTOMER_TABLE 中 CUSTXML 列的数据,那么可以在查询中指定 CUSTXML 列的路径作为目标。
在上面的查询中,不但搜索、获取和合并了数据库中存储的 XML 文档部分,还在产生的 XML 中添加了新元素。另外,hardeep 被隐式转换为 XML 类型(xs:string)。
对比数据库查询和 Java 应用程序代码
如果将上面的查询与第 1 部分中的 Java 代码(清单 6. 重写应用程序来使用 XML 模型)做一下对比,就会发现它们的逻辑非常相似。
一个更精细的示例
现在考虑一个比较精细的场景,这个场景还要计算每个商品的保险费。为了让这个场景有点儿难度,保险费不但每天变动,而且随价格变化。这意味着,不但要向查询传递 customerid,还要传递保险费率。现在,假设您每天在保险公司提供的一个 Web 服务中查询最新的保险费率。保险费率信息采用 XML 文档的形式。
Select XMLROW (customerid, firstname, lastname OPTION as attributes ROW Customer)
from customer_table where customerid=?
还可以在关系数据和 XML 数据之间创建联结。在这个示例场景中,如果有第三个表,其中包含购买商品的产品说明,而且这是一个关系表,那么可以使用商品 ID 执行联结,从而获得购买的每种商品的产品说明。
图 5. 联结关系列和 XML 列
Select details, weight from SQLPRODUCT, ITEM_TABLE
where xmlexists ('$itemxml/item[@itemid=$pid]'
passing ITEM_TABLE.ITEMXML AS "itemxml", SQLPRODUCT.PID AS "pid" )
values(xmlquery('
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $custid
return (
$Customer0/Item,
db2-fn:sqlquery(
''select xmlrow(details, description, weight option ROW "description")
from sqlproduct where pid= parameter(1)'', $Customer0/Item/@ID))
' passing cast( ? AS varchar(255) ) as "custid" ))
因此,即使一部分数据位于关系表中,一些数据是 XML,现在都可以在 SQL 查询、XQuery 或这两者中在 XML 数据和关系数据之间进行动态联结。
在某些情况下,性能可能不是大问题,因为:
能够为数据库中存储的 XML 文档创建基于 XPath 表达式的索引。
create index custfname on customer_table(info) generate key
using xmlpattern '/Customer/@firstname' as sql varchar(64)
因为数据库模式更简单,所以减少了所需的联结数量。
因为现在可以在查询中缩减数据,然后再把数据发送给应用程序,所以可以减少 I/O。
随时可以使用 SQL/XML 函数(比如 XMLTable)将 XML 文档中的关键信息提取到关系列中,并为它们创建关系索引。
可以为 XML 文档创建文本搜索索引。
结束语
XML 已经取得了稳固的地位。大多数行业和政府组织都对他们的 XML 模式做了标准化,并要求电子文档必须符合这些模式。既然通过线路交换的 B2B 数据已经采用了 XML 格式,为什么不在数据库中按原样(pureXML)存储这些数据呢?将数据存储为 XML 之后,可以使用 XQuery 和标准的 SQL/XML 对它进行编制索引、查询、检验、操作、转换和更新。随着越来越多的应用程序逻辑被放在查询中,数据库可以以 Web 服务和 feed 的形式公开它的存储过程,从而成为面向服务体系结构(SOA)环境中活跃的参与者。
“旧的秩序已经改变了,新的秩序正在形成。”(The old order changeth, yielding place to new.) Morte d'Arthur
参考资料 学习
您可以参考本文在 developerWorks 全球站点上的 英文原文。
“ISV success with DB2 Viper”:准备将应用程序、例程和脚本迁移到 DB2 Viper。
关于 DB2 XML 的技术文章:寻找更多关于 DB2 和 XML 的文章。
“DB2 Viper 快速入门”(developerWorks,2006 年 4 月):了解如何创建管理 XML 数据的数据库对象以及用 XML 数据填充 DB2 数据库。
“用 SQL 查询 DB2 XML 数据”(developerWorks,2006 年 4 月):了解如何用 SQL 和 SQL/XML 查询 XML 列中存储的 DB2 数据。
“使用 XQuery 查询 DB2 XML 数据”(developerWorks,2006 年 5 月):了解如何用 XQuery 查询 XML 列中存储的数据。
XML Programming with PHP and Ajax:在面向服务体系结构和其他业务场景中使用 DB2 9 的 XML 功能。
“结合使用 DB2 原生 XML 与 PHP”(developerWorks,2005 年 11 月):了解如何使用 DB2 Universal Database for Linux, UNIX, and Windows 的新版本中的本机 XML 功能简化应用程序代码和关系模式。
“Native XML Support in DB2 Universal Database”:对新的 DB2 XML 支持和传统关系数据库技术进行对比。
developerWorks China Information Management 专区:学习关于 DB2 的更多知识。在这里可以找到技术文档、how-to 文章、培训、下载、产品信息等等。