|
XML 问题 #9:SQL 查询中的 DTD 和 XML 文档广告 XML 问题 #9:SQL 查询中的 DTD 和 XML 文档
David Mertz, Ph.D. (mertz@gnosis.cx) 本专栏讨论了可以不依赖 RDBMS 生成可移植 XML 结果集的公众域 sql2dtd 和 sql2xml
实用程序。从关系数据库中抽取数据的 SQL 查询可以提供非常实用且特殊的文档类型信息,用于以 XML 表示查询结果。 一些近期的 RDBMS(至少包括 DB2、Oracle,可能还有其它一些 RDBMS)都附带了用于导出 XML 的内置(或者至少可选的)工具。不过,在本专栏中讨论的工具都具有普遍性;特别是,由这些工具生成的 DTD 对于对不同 RDBMS 执行的相同查询都是完全相同的。我希望这对实现数据透明性的目标会有所帮助。 过于简化 SELECT * FROM BOOKPRICE; 我可以直接将它转换成如下文档 BOOKPRICE.xml: 清单 1. BOOKPRICE.xml 文档 <?xml
version="1.0"?> 为数据库中的每个表创建了类似的 XML 文档后,您就拥有了整个数据库的快照。 适当简化 第二个问题比第一个更有趣。在某种意义上,“DASD 很廉价”,带宽也变得越来越廉价("DASD" 是 IBM 对“硬盘”的旧称;这个措词在设计上很陈腐)。因此单单效率不一定就是最重要的因素。更为重要的是,您几乎不会想要将数据库的全部内容与伙伴/部门/用户等进行交流。有时候,一些内容是专用的;而几乎任何时候,大多数内容与特定用户并没有任何关系。 将有用的 SQL 查询结果转储到 XML 中比将原始表转储到 XML 更有意义。而为了将 XML 事务或馈送所需的确切语法分析和处理的预期规律化,将 DTD 与这些有用的查询进行关联仍然会比较好。这两种有趣的操作恰好是公众域 Python 实用程序 sql2dtd 和 sql2xml 能够实现的。 假设 A 和 B 各自有其自身的内部数据存储器策略(例如,在不同的 RDBMS 中)。各自维护所有种类的相关信息,这些信息与 A 和 B 之间的交互没有关系,但它们又都具有一些希望共享的信息。假设,遵循这样的路线,A 需要与 B 循环地就特定种类的数据集进行通信。A 和 B 可以做的一件事是同意 A 将定期向 B 发送一组 XML 文档,每个文档都符合事先一致认可的 DTD。一个传输中的特定数据将随时间而有所不同,但有效性规则已事先指定。只要 A 和 B 知道它们之间的协议,就可以执行它们的编程。 生成 DTD 不过通常存在一种更快速的方法 -- 往往利用现有导出/导入过程的一种方法。“标准查询语言 (SQL)”是一种能够确切表达 RDBMS 数据库中您所感兴趣的数据的极其简洁的方法。尝试将例如 XPath 或 XSLT 这样的 XML 原始技术合并到关系模型上可能不太自然,尽管它们必定可以在 XML 的基本分层模型中表达查询功能。 许多组织已经开发出为实现已知任务的、经过了彻底测试的几组 SQL 语句。事实上,RDBMS 往往提供了用于优化已存储查询的方法。虽然肯定有一些为数据交换而设计的丰富的 DTD 比较有意义的情况,但在许多或者大多数情况下,在 SQL 查询中隐式地使用结构信息作为 SQL 数据传输的(自动)基础是种很好的解决方案。 虽然 SQL 查询可以以复杂的方法来组合表数据,但所有 SQL 查询的结果都是相当简单的“行与列”的排列。在查询输出中,列的数量是固定的,每行填入了每个固定列的值。(即,除了数量上没有改变以外,无论是值的类型还是列名在 SQL 结果中均无改变 -- 即使它们可能在 XML 文档中有所改变)。XML 表示元素复杂嵌套模式的潜力在表示 SQL 结果中并没有得到深层的体现。虽然如此,SQL 查询的一些重要方面可以而且也应该在简单的行/列位置以外以 XML DTD 表示。 要表示 SQL 查询中的哪些内容? 在编写 sql2dtd(和帮助规划 Scott Hathaway 的 sql2xml)时,我做了一些决定,确定了哪些属于数据传输的部分,哪些位于发送方设置的内部(不需要以 DTD 表示)。清单 2 所显示的样本 XML(带有作为内部集的 DTD)输出有助于说明这些决定(该输出完全从作为属性包含的 SQL 查询生成;当然,是在对合适的数据库运行时): 清单 2. 带有作为内部集的 DTD 的样本 XML 输出 <?xml version="1.0"?> <SQL> 这个简单的 XML 文档实际上可以包含比人们最初时所注意到的更多的元数据。当然,通过将 SQL 本身作为根节点的一个属性包含在内,人们可以重新构造 SQL 中固有的任何事物。但这样做需要对 SQL 重新进行语法分析,sql2dtd 已在文档中表示过它,因此通常这没有必要。 CALC 属性的规范包含这样一个事实,即 XML 包含了计算过的元素。因为计算过的表达式可能很长,并且可能包含对于 XML 标记来说非法的字符,所以计算过的列仅由它们的位置命名。不过,加入元素内容的特定计算是作为标记的一个属性包含在内的。为了避免在 XML 主体中重复属性,它在 DTD 中指定为 #FIXED。 如果使用计算过的列,计算往往反映使用 "GROUP BY" 修饰符对列所进行的分组。所有这样的分组都在根元素的 GROUP_BY 属性中列出。 而且,如果使用了 "ORDER BY" 子句,每个 <row> 标记就会带有指定输出数据序列的 num 属性。不过,如果结果集是无序的,则不使用 num 属性。 让我们考虑一下在 DTD 中有什么东西没有表示,就会发现它实际上确实属于 A 的内部数据表示,而不属于发送的消息。 除了嵌入的原始 SQL 查询以外,没有保留用于查询数据的一个或多个表的表示("FROM" 子句)。特殊的表组织只不过不是 B 需要感兴趣的一些事物。事实上,A 可以在有适当传输协议之后彻底地修改其数据库设计;但只要通过一些手段抽取相同的字段(列),B 就不需要担心这一点。尤其是,因为 "AS" 子句覆盖了实际的表的列名,所以有可能继续发送在 A 数据库中不再拥有任何直接文字意义的 XML 元素。 在 sql2dtd 设计中最重要的一点是忽略了 "WHERE" 和 "HAVING" 子句(以及 JOIN、DISTINCT 和 ALL 修饰符)。和表名一样,将数据从 A 的那些表中取出所必需的特定联接和过滤器不是 B 应该担心的问题。如果 A 碰巧需要将一些表联接在一起以获得一些数据,那只是 A 的一个标准化策略。B 可以使用也可以不使用任何类似的策略(对于不同的数据子集),两种方法都不用担心 A 的操作。出于相关但稍微不同的理由忽略过滤器(主要使用 "WHERE" 子句或 "DISTINCT" 修饰符)。不管出于何种商业原因,如果 A 只需要告之 B 那些其 whatzit 大于 25 的 woozles,从 B 的角度来说,它只是属于 woozles 的性质。即,A 可能对 B 不关心的 woozles 的一个子类感兴趣;但是 A 需要通过使用过滤器来获得感兴趣的内容(与不拥有它们,或将它们放在另一个表中相反)这一特定事实并不是 B 需要担心的。从这一方面来说,sub-select 只是另一种过滤器。 结束 这些工具只对 A 和 B 之间预期大约一半过程有所帮助。A 和 B 可以快速地使用这些工具达到 DTD,A
可以同样快速地生成符合这些 DTD 的输出 XML 文档。但 B 最终仍需要执行语法分析、存储和处理这些接收到的文档所涉及的所有工作。以后的专栏将更详细地讨论
B 的任务。 与我同为 XML 专区专栏作家的 Uche Ogbuji 曾为 LinuxWorld 写过一篇有趣的文章,是关于有些不一样的 RDBMS/XML 连接的元素的。除了写了一篇好文章以外,Uche 还提供了一个相关参考资料的详细列表。 可以联机获得我的 sql2dtd。 请查看 Scott Hathaway 的相关 sql2xml。 Matt Sergeant 的 IBM 的 DB2 Extender 页面提供了 DB2 如何使用 XML 的基本概述,并带有到可作为 PDF 文件查看的详细白皮书,以及到 DB2 Extender 下载的链接。 参阅 David Mertz 以前的“XML 问题”专栏文章: XML 问题 #1 介绍 Python xml_pickle 对象。 XML 问题 #2 描述如何使用 Python 的 xml_objectify。 XML 问题 #3 介绍 DocBook。 XML 问题 #4 继续介绍如何使用 DocBook 构建旧的文档档案。 XML 问题 #5 说明如何通过 XSLT 将 XML 文档转换成 HTML。 XML 问题 #6 比较了半打 XML 编辑器,同时特别着眼于那些适合于有大量文本的文档的工具。 XML 问题 #7 将 DTD 与 XML Schema 进行了权衡,并建议无论 W3C XML Schema 规范有多么成熟,开发者在什么情况下需要坚持使用 DTD。 XML 话题 #8 讨论了由计算机科学家概念化出来的数据模型的抽象理论是如何帮助我们开发特定的多表示数据流的。 关于作者
如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐 jill.jiang@amteam.org | 021-51096826-112 | 在线联系 |
节能与优化IT 企业CIO过冬良策当前金融危机的影响还在继续漫延,很多企业都在苦寻过冬的良策,在这种情况下,节能与优化技术与产品无疑成为CIO们关注的首要对象,本次选题就是针对节能与优化IT来为CIO们提供过冬的良…… |
|
|