DB2 存储和检索 XML 数据
自从 IBM 在 DB2 Universal Database 5.0 中引入对象关系技术以来,Internet 技术、分布式计算和最近的可扩展标记语言(Extensible Markup Language,XML)对计算产生了很大的影响。XML 使人们将目光聚焦到以文档为中心的计算、新的办公文档标准格式以及 SQL 标准的继承者 SQL/XML:2003 上。
内容管理和面向 Web 的应用程序常常需要存储和检索 XML 数据。XML 为数据集成、过程集成和企业信息集成提供了基础。XML 还为新的分布式计算模型提供了支持,包括 Web 服务、网格服务和面向服务架构(SOA)。
DB2 9 能同时处理 XML 和 SQL,这是它的一个很大的优点。它支持一个数据库平台同时用于数据处理、文档处理和 SOA。对于经常接触 SQL 和表结构的人来说,XML 为结构化文档思想和新的查询技术打开了一扇门。
pureXML 的作用
IBM 提供了 DB2 9 的一个测试活动,使早期采用者能够用新的 DB2 SQL/XML 平台测试他们的软件。在技术采用周期中,早期采用者通常是一些熟练的公司以及开发工具和中间件的独立软件供应商(ISV)。其中一些早期采用者共享了他们在新技术方面的经验。
其中一家公司就是 Storebrand Group,这是挪威的一家金融服务公司,提供养老金计划、人寿保险、银行业务和资产管理。在挪威,养老金计划是强制性的;1,400 家公司都与 Storebrand 签订了养老金协议。在 1996 年,Storebrand 采用了一种面向服务的体系架构(Service-Oriented Architecture, SOA),这种架构使用标准通用标记语言(Standard Generalized Markup Language,SGML)来格式化显示消息。它使用 DB2 存储用于同步、审计和其他用途的消息。在 DB2 9 之前,Storebrand 将 XML 分解(打碎)或将整个文档存储为 CLOB 列。DB2 9 的 pureXML 技术将 XML 文档存储为它们的本地格式,因此采用这种技术可以带来一些优点。
Storebrand 的高级企业架构师 Thore Thomassen 说道,以原生的形式存储 XML 可以减少应用程序中的 I/O 代码,而且,与分解或 CLOB 方法相比,这种方法要求的数据库技能更少。DB2 9 的 XML 类型还为搜索和操纵提供了更大的灵活性。“我们有一些案例,在这些案例中,我们知道在一个 CLOB 中有 XML 格式的业务关键数据,但是如果不编写应用程序,就不能访问该数据。”Thomassen 解释道。
World Wide Web Consortium (W3C) 推出的 XML Query Language (XQuery) 支持根据内容和结构查询文档。为定位文档中的片段,查询需要在一个树型结构中遍历或匹配一个模式的逻辑。SQL INSERT 查询不必维护行之间的顺序,但是在将 XML 文档存储为本地格式时,保持标记的顺序却非常重要。只有保持文档的结构,才能使用文档中的位置作为搜索标准。
Thomassen 说,使用 XPath 和 XQuery 简化了应用程序的开发,并为 pureXML 应用程序提供了更大的透明性和重用性。他的小组发现 XML 和 SQL 查询混合使用产生的威力 “非常强大”。
OpenLink Software 是一家专门提供中间件的独立软件供应商(ISV),这家公司也测试了 DB2 9。该公司的 CEO Kingsley Idehen 这样解释其价值:“DB2 中的本地 XML 数据类型支持对于新兴的跨 ODBC、JDBC 和 ADO.Net 的数据访问中间件层的 SQL 与 XML 集成标准作出了重大贡献。”
DB2 从 1999 年开始就支持 XML,那么,DB2 9 的革新之处在哪里呢?
pureXML 和 DB2 XML Extender
IBM 早期对 XML 的支持以 DB2 XML Extender 的形式提供,DB2 XML Extender 将 XML 当作 xcolumns 或 xcollections。随后又出现了用于处理消息队列中 XML 的存储过程和函数。DB2 9 则引入了一种新的 XML 存储模型。
DB2 XML Extender 把 XML 当作 CLOB 或可变长度的字符串(VARCHAR),而 DB2 9 则将 XML 实现为一级数据类型。这意味着您可以在数据定义语言(DDL)语句、存储过程和函数(包括 SQL/XML:2003 XML 发布函数)中使用 XML 类型。虽然 IBM 将继续支持 DB2 XML Extender,但是 DB2 XML Extender 的功能已经被 DB2 9 中的 pureXML 支持取代。
pureXML 架构
将 XML 集成到 SQL 平台的一种常见方法是通过映射到关系代数来支持 XML 查询。这种方法使用已有的关系引擎,DB2 XML Extender 从 DB2 UDB 6.1 开始就使用这样的关系引擎。在 DB2 9 中,一个引擎(为 XML 和关系数据进行了优化)处理关系和 XML(分层)数据;然而,这两种数据类型处在不同的存储层中。新的引擎将 XML 文档看作一个经过解析的、带注释的树型结构,并支持文档片段的索引。
与新的 XML 数据存储一道,DB2 9 支持 SQL/XML:2003 XML 类型、SQL/XML 函数和 XQuery。DB2 9 让您可以单独使用 XQuery 或 SQL 查询 XML 数据,还可以使用调用 SQL 的 XQuery 或者执行 XQuery 表达式的 SQL/XML 函数来查询 XML 数据。
索引
DB2 9 为索引 XML 数据提供了灵活的功能。通过指定一个 XML 模式,可以在一个 XML 列中的文档的任何路径或子树上定义 XML 索引。这种方法可以很好地控制哪些数据要索引,哪些数据不要索引。DB2 的 XML 索引将路径和值映射到文档和节点实例。
另外,DB2 的 Net Search Extender 通过将文本标志映射到包含它们的文档,提供用于全文搜索的索引。全文索引和全文搜索可用于整个文档,也可用于文档的片段。
编码和串行化
在 DB2 中,为大型机(EBCDIC)、Linux、Unix 和 Windows(ASCII),以及 XML、Java 和 .Net 应用程序(Unicode)使用不同的字符集并不鲜见。而且,DB2 预编译器在编译之前将嵌入式 SQL 源代码转换为 Unicode。
当在机器之间传输数据时,DB2 常常必须对字符集进行转换,使之变成能被接收方机器使用的格式。Coded Character Set Identifier (CCSID) 定义是标识一个码页的惟一值。它们提供 DB2 for Linux、Unix 和 Windows 中的双向布局转换。当两台机器有不同的码页或 CCSID 时,DB2 将转换输入和输入字符数据,例如将 DB2 Connect 服务器码页转换成主机 CCSID,反之亦然。接收方机器则对收到的数据进行转换。
当串行化 XML 时,DB2 可以在 XML 输出的开头添加一个编码声明。当将应用程序变量或编码 XML 类型存储在一个 XML 列中时,DB2 数据库管理器将检查编码声明,并将它映射到一个 CCSID。
对 Unicode 和 CCSID 的支持还包括 DB2 客户机/服务器连接性和编程 API 方面的变化,例如调用层接口(CLI)和嵌入式 SQL。使用动态 SQL 的嵌入式 SQL 程序为主机变量使用 SQL descriptor area (SQLDA)。为支持 XML 数据,嵌入式 SQL 程序必须更新 SQLVAR 的 sqlname 字段,表明一个基本类型包含 XML 数据。
带注释的 XML 模式
当执行一条 CREATE DATABASE 命令时,用户可以选择是否在 DB2 数据库中包括 XML 支持。如果选择包括数据库对象,那么 DB2 将使用 Unicode 字符集创建一个数据库。运用这种 XML 选项可以避免对数据库分区。当生成一个数据库时,第二个决定是使用系统管理的空间还是使用数据管理的空间。不管是对于关系数据库还是 XML 数据库,最佳选择是数据库管理的空间。
除了用于 SQL 访问的新的 XML 类型外,DB2 9 还包括 W3C XML Schema 类型。XML 模式语言比 SQL 有更多的基本类型,它还支持通过派生得到的复杂类型。通过智能使用 SQL 数据定义语言(DDL),还可以提供数据完整性和类型安全。XML 模式语言为 XML 应用程序和 XQuery 提供了类似的优点,但是 XQuery 还可以对没有模式的文档进行操作。
带有多个模式(包括相同模式的多个版本)的文档,可以在一个 XML 列中共存。一个 XML 文档可以包括多个类型,并且可以用 XML 模式来验证。DB2 9 为验证文档提供了模式注册。它在由编目表、视图和存储过程组成的数据库编目中维护一个 XML 模式库(XSR)。
当验证模式时,XML 模式注册引擎产生类型注释。因此,支持 XML 的 DB2 数据库可以在查询执行期间使用文档和带注释的 XML 模式。通过使用带注释的模式分解,可以将 XML 转换成关系数据。DB2 使用注释将 XML 文档中的元素和属性映射到目标数据库表。为了配合带注释的模式分解,DB2 9 提供了六个新的存储过程(xdbDecompXMLxxxxx)。
通过创建支持 XML 的数据库,以及注册 XML 模式,可以压缩应用程序的内存需求。对于较大的模式,开发人员可能需要增加应用程序堆(APPLHEAPSZ)。
SQL DDL、外部例程、UDF、存储过程和触发器
由于 DB2 9 实现了 XML,因此可以在 SQL DDL 语句、存储过程和函数(包括 SQL/XML 函数)中使用 XML。DB2 以一种内部格式存储 XML 列的值,但是 XMLSERIALIZE 函数可以将它转换成字符串值。
您可以创建 XML 列上的触发器,还可以在外部函数和存储过程中使用 XML 类型,但是在触发器中不能引用 XML 列的 before 或 after 值。要在存储过程中使用 XML 类型,可以将 XML 类型的参数包括在 CREATE PROCEDURE 参数签名中。对于使用 CREATE FUNCTION 的标量函数或表函数,这个过程也是类似的,但是对于外部 OLE DB 函数而言,XML 类型不是有效类型。DB2 隐式地解析和串行化用于传递给外部例程做参数的 XML。也可以使用 XMLPARSE 函数显式地解析 XML 数据。
还可以在用 C、C++、C#、Cobol、Java 和 Visual Basic (VB) 编写的程序中使用 XML 类型。C 和 C++ 程序员可以用嵌入式 SQL 或 CLI 访问 XML 类型;C# 和 VB 程序员则用 DB2 .Net Data Provider 访问 XML;而 Java 程序员则用 JDBC 或 SQLJ 访问 XML。如果是编写存储过程和函数所使用的外部例程,那么可以像使用 CLOB 那样使用 XML 类型。可以先将外部例程参数声明为 XML 类型,然后使用 CREATE PROCEDURE 和 CREATE FUNCTION 语句在数据库中注册它们。它们规定将 XML 类型存储为 CLOB,并且,DB2 在将它传递给外部例程之前串行化 XML。
类型和数据访问
C/C++ 以及脚本编制解决方案(例如 PHP 和 Perl)常常使用 ODBC 接口来访问 SQL 数据。DB2 CLI 扩展了 ODBC 3.51 API,它提供了对附加类型(包括新的 XML 类型)的支持。
在编写 CLI 程序时,XML 列的 SQL 数据类型是 SQL_XML,对于 C 程序,XML 列的默认数据类型是 SQL_C_BINARY。允许的转换包括 SQL_C_CHAR、 SQL_C_WCHAR 和 SQL_C_DBCHAR。XML 列的默认精度为 0,不过这是一个用于外部例程的定义长度。
IBM 不赞成为 DB2 9 使用 type 2 JDBC 驱动程序。它建议迁移到 IBM DB2 Driver for JDBC 和 SQLJ,后者是组合了 type 2 和 type 4 特性的一种驱动程序。它支持 Java Transaction Service (JTS)、Java Transaction API (JTA)、JDBC 3.0 API 和具有 JDBC 对等物的 SQLJ 功能。
要在 Java 中访问 DB2,开发人员可以通过 SQLJ 使用静态 SQL,还可以通过 JDBC 使用动态 SQL。Java 没有 XML 类型,所以调用 JDBC GetTypeInfo 元数据方法将报告 XML 列的类型为 java.sql.Types.OTHER。
通过使用 JDBC ResultSet.getXXX 方法,可以从列中检索整个 XML 列,或者一个序列。当使用 JDBC getXXX 方法检索 XML 数据时,数据是一种串行化字符串格式。getXXX 方法将以与方法名称相应的格式输出结果(例如 getAsciiStream)。对于 ResultSet.getObject,可以将对象强制转换为 DB2Xml 类型,将它赋给一个 DB2Xmlobject,并使用 DB2Xml.getDB2XXX 方法将数据输出为所需的类型。
一个增强的 Microsoft Visual Studio 2005 插件集包括对使用 DB2 9 中的 XML 数据构建和测试 .Net 应用程序的支持。DB2 提供了用于 OLE DB 和 ADO.Net 的提供程序,包括 DB2 .Net Data Provider、OLE DB .Net Data Provider 和 DB2 Data Provider for .Net Framework 2.0。OLE DB Provider 和 OLE DB .Net Data Provider 不支持新的 XML 类型。为了使用 ODBC .Net Data Provider 访问 XML 列,可以将它映射为 SQL_LONGVARCHAR。
使用 SQL 和 XQuery 的查询
正如 Storebrand 的 Thomassen 所说的那样,DB2 9 提供了使用 SQL、XQuery 或结合使用两者的能力。要对 SQL 和 XQuery 作一个详细的比较并非易事,所以可以想像一下集成这两种语言的复杂性。为了理解 XQuery,还必须掌握 W3C 各种规范(推荐标准)中定义的概念,包括名称空间、模式和 XPath 表达式。
SQL 与 XQuery 有相似之处,例如连接操作和用户定义函数,但是两者之间也有重大的区别。XQuery 只涉及二值逻辑,而 SQL 中还可能存在 null 值,因此它属于三值逻辑的范畴。XQuery 的名称比 SQL 更复杂,并且 XML 模式是可以演化的。XML 模式可以提供类型检查,但是 XQuery 可以对没有模式的文档进行操作。未来版本的 XQuery 规范中还将包括更新功能和全文搜索。
DB2 以不同的解析器为 XQuery 和 SQL 提供支持,并且不支持从 XQuery 到 SQL 的翻译。DB2 为这两种语言使用一个公共的查询编译器,对于用任意一种语言编写的查询,都会通过使用一个查询图来建模查询,为查询生成一个执行计划。在生成执行计划时,DB2 基于成本的优化器可以使用 XML 和关系索引。
SQL/XML 标准引入了一组用于操作 XML 数据实例的函数(XMLQUERY、 XMLEXISTS 和 XMLTABLE)。DB2 9 还使用以下函数:XMLParse、 XMLValidate、 XMLSerialize、 XMLCast。SQL/XML 标准引入了用于将关系数据转换为 XML 的函数。DB2 9 中的发布函数包括 XMLElement、XMLAttributes、XMLForest 和 XMLAgg。
Web 服务
自从在 2000 年揭开了 Web 服务的面纱以后,IBM 参与了一些规范和软件解决方案的开发,开发的目的是促进 SOA 被广泛采纳。Web 服务和网格服务使用 SOAP 在提供者和消费者之间交换 XML 编码的消息。Web 服务和网格服务使用一个被称作 Web 服务描述语言(WSDL)的 XML 词汇表来描述服务。DB2 包括一个 Web 服务提供程序,它可以使用 Web 服务。
由于 XML 对于 Web 服务和网格服务的运行是必不可少的一部分,因此 XML 处理的开销会引起性能方面的代价。DB2 的本地 XML 引擎、解析后的文档和带注释的模式将降低这种开销,因为它们可以减少交换 XML 编码的消息以及在磁盘上和消息队列中查询消息时的解析和验证工作。
DB2 有一个嵌入式应用服务器来运行随产品打包的 Web 服务。IBM 还开发了 Web Object Runtime Framework (WORF),这个软件支持使用 DB2 作为 Web 服务提供程序。WORF 可以为服务生成 WSDL,并且支持通过 HTTP GET、POST 和 SOAP 绑定访问服务。
WORF 支持多种从 DB2 数据库检索数据的模式。WORF 用户创建一个文档访问定义扩展(Document Access Definition Extension,DADX)文件,这是一个 XML 文件,其中描述了 XML 文档节点与关系数据之间的映射。DADX 文件支持 SQL 操作和使用 XML 集合的操作。如果不使用 WORF,那么就不得不编写代码来创建一个提供程序,包括生成 WSDL 服务描述。
学习曲线
采用 DB2 9 的开发人员和 DBA 将体验到一些新功能,这些新功能影响到数据访问 API、文档查询、SQL 语法、查询优化等。因此将会有一个学习曲线,但是新增的功能使 SOA、Web 服务、网格服务和文档管理应用程序更强大、更灵活,同时也更容易开发。