以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 DTD/XML Schema 』 (http://bbs.xml.org.cn/list.asp?boardid=23) ---- XML 问题 #9 SQL 查询中的 DTD 和 XML 文档 (http://bbs.xml.org.cn/dispbbs.asp?boardid=23&rootid=&id=12030) |
-- 作者:anchen0617 -- 发布时间:11/13/2004 2:43:00 PM -- XML 问题 #9 SQL 查询中的 DTD 和 XML 文档 本专栏讨论了可以不依赖 RDBMS 生成可移植 XML 结果集的公众域 sql2dtd 和 sql2xml 实用程序。从关系数据库中抽取数据的 SQL 查询可以提供非常实用且特殊的文档类型信息,用于以 XML 表示查询结果。 前一“XML 话题”专栏讨论了各种数据模型的一些基本理论和它们的优势。得出的一个结论就是 RDBMS 已被普遍接受(有充分的理由),并且在这种环境中,最好将 XML 看作是在各种 DBMS 之间传送数据的一种方法,而不是替代 DBMS 的事物。虽然 XPath 和 XSLT 可用于某些特定的“数据查询”,但它们的应用远不及 RDBMS 和(尤其是)SQL 的应用广泛和普遍。不过,由于篇幅限制,我将在以后的专栏中讨论 XPath 和 XSLT 的具体性能(和限制)。 一些近期的 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 的任务。
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
46.875ms |