论文部分内容阅读
摘 要:用XML表示的半结构化数据越来越普遍,同时,大量的结构化数据组织存放在关系数据库中。如何集成这些不同结构的数据成为了研究的一个热点。本文设计了一种关系型数据源包装器,它主要具有两个功能模块,一个负责将XQuery查询转换为SQL查询,称为查询转换器;另一个负责将SQL查询返回的元组转换为XML数据格式,称为结果产生器。包装器是一种软件,它相当于数据源的外衣,不影响数据源的本身,它是异构数据集成系统的一个重要组成部分。
关键词:关系数据 查询 转换 XML 包装器 设计
中图分类号:TP311文献标识码:A文章编号:1673-8454(2007)09-0021-03
一、引言
包装器是自治异构数据源集成系统中的重要组成部分,随着与XML有关的标准不断制定和完善,越来越多的数据被用XML表示,然而必须注意的一个事实是,目前和在一个可以预见的未来,大部分应用系统,甚至是新的基于Web的应用系统,仍然将关系数据库系统作为数据存储和查询的首选。关系数据库系统的可靠性、技术的成熟性、丰富的工具、高性能等,都决定了这一点。本文探讨在自治异构数据源集成系统情境下,如何将XQuery查询翻译成SQL查询,如何将关系数据转换为XML数据表示。[1]
1.查询转换器的设计
(1)将XQuery子查询重写成XML文档
当包装器接收到一个针对关系数据源的XQuery查询时,例如要查询订单号oid为1001的Yang Hui客户定购的图书,如图3所示。首先进行查询重写,将关系数据源上的子查询(XQuery形式)重写成查询XML文档,将被重写成如图4所示的XML文档。
在图4的XML文档中,“Queries”节点包括“Query”、“From”和“where”三个子节点,其中,“Query”子节点用于描述查询内容;“From”子节点表示查询的数据库表;“Where”子节点用于描述查询条件。该文档的含义是:查出订单号为1001的Yang Hui客户定购的图书(包括oid、user、address、bid、title、price),接下来,系统会将生成的查询XML文档转换成SQL语句,进行下一步处理。
(2)将查询XML文档转换成SQL语句
对于关系型数据库的数据源,可采用模板法来定义查询 XML文档与SQL语句之间的映射关系,采用基于DOM的Java解析器ProjectX来解析XML查询文档,提取出其中的查询内容,组织成 SQL语句。[3]
为了使系统可以很容易地将文档的元素和属性映射到其它数据结构或对象分级结构中,也为了在客户端的浏览器和服务器之间传输文件变得方便和可靠,便于XML文件被机器正确识别并理解文档的内容和含义,使得用户可以使用XML文件作为一种中介体让数据在不同的数据源或应用程序之间灵活地进行交换传输,我们需要对XML查询文档定义严格的文档模型DTD,规定各个标签的含义,以及与数据库全局视图中的各部分的一一对应关系。以图4的XML查询文档为例,其对应的文档模型DTD如下:[3]
<!DOCTYPE Query[
<!ELEMENT Query(Item+,From,Where*)>
<!ELEMENT Item(#PCDATA)>
<!ELEMENT From(#PCDATA)>
<!ELEMENT Where(fiel)>
<!ELEMENT fiel(#PCDATA)>
<!ATTLIST fiel name CDATA #REQUIRED>
]>
模板法要求定义固定的模板,因此对于关系型数据库、面向对象型数据库及其他形式的数据源,只要事先定义好对应该数据库查询语言的XML模板的DTD,就能让应用程序识别并转化XML子查询。
在集成系统中,发送给关系数据源的XML查询文档如图4所示。查询转换器将该XML查询文档转换为如下的SQL语句:
SELECT oid,user,address,bid,title,price
FROM order,book
WHERE user=’Yang Hui’ and oid=’1001’
(3)实现策略
//使用IBM XML4JApache Xerces创建一个DOM解析器
import org.apache.xerces.parsers.DOMParser;
DOMParser parser=new DOMParser();
//解析一个XML文档,生成一棵DOM树
try{
DOMParser parser=new DOMParser();
Parser.parse(filename);
Document doc=parser.getDocument();
}
//输出节点的子节点
NodeList children=node.getchildNodes();
If(children!=null){
Int len=children.getLength();
For(int i=0;i Node child=children.item(i);
}
//定义一个字符串变量sql来存储SQL语句
String sql=“SELECT ”;
//取出各个查询项
For(int i=0;i //找到Item节点,组成SQL语句中的SELECT部分
if(children.item(i).getNodeName().equalsIgnoreCase(“Item”)==ture)
sql=sql children.item(i).getNodeValue() “,”;
//找到From节点,组成SQL语句中的FROM部分
if(children.item(i).getNodeName().equalsIgnoreCase(“From”)==ture){
sql=sql.getSubString(0,sql.getlength()-1) “ FROM ”;
sql=sql children.item(i).getNodeValue() “,”;
}
//找到Where节点,组成SQL语句中的WHERE部分
if(children.item(i).getNodeName().equalsIgnoreCase(“Where”)==ture){
sql=sql “ WHERE ”;
for(int j=0;j Node fiel=children.item(i).getChildNodes().item(j);
sql=sql fiel.getAttributes() “=”;
sql=sql fiel.getFirstChild().getNodeValue() “ and ”;
}
sql=sql.getSubString(0,sql.getLength()-3);
}
2.结果产生器的设计
(1)关系模式映射为XML Schema
结果产生器是数据源包装器的一部分,它需要完成的主要功能是将从关系数据源得到的查询结果记录映射成XML格式。
关系数据模型具有“表”结构表示、扁平和规范化的特点。相反,XML数据却具有任意层次的嵌套结构和非规范化的特点,良好地表示二者数据之间的映射关系是数据格式转换的起点。XML语言本身的灵活性为我们找到问题的答案提供了可能。以下是从关系数据库的关系模式映射为XML Schema的方法步骤。
1)获取关系表的所有信息;2)用恰当的XML命名空间和目标模式空间信息创建一个模式标签;3)建立对根元素的描述;4)建立对表的描述;5)建立对记录元素的描述;6)建立对字段元素的描述;7)数据类型的描述。
运用上述模式转换的方法,结果产生器可以将关系模式转换成XML Schema文档。
(2)基于查询的映射
基于查询的转换方法一般都是基于上面讨论的简单映射,但由于在实现中有查询和加标记这两大处理,因而有先查询后加标记和先加标记后查询这两类不同的方法。如果先对完整的关系数据库进行转换,当表的数目和表中的字段数都较多时,时间性能将大大下降,代价过高。因而,我们使用的方法是先对关系数据库进行查询,将查询结果以视图的形式组织,得到较小的数据集,然后再对视图进行映射转换。
针对XML文档是树形结构的特点,我们提出一种基于树的方法。该方法的原理是先构造出复杂查询的结果视图;将该结果视图看成一个单一的表,然后将其映射为Schema;再根据Schema为该结构建立一棵树;将查询结果插入到树中合适的位置上;按深度优先、先根遍历的方法遍历该树,即可得到目标XML文档。
对于关系数据源上的查询,为了得到目标XML文档,可先利用SQL创建该文档的关系视图,根据该视图按照上面的映射规则可得相应的Schema;根据Schema建立一棵用于表示该数据模式的树。下面是对这样的一棵树进行深度优先、先根遍历的算法(以自然语言的形式给出):
traversal(p:treepoint);
访问根节点;
访问根节点的所有属性节点;
递归地遍历根节点的firstsubelement域所指的树;
其中对根节点以下的各级元素节点,遍历的算法为:
访问当前节点;
访问当前节点的所有属性节点;
递归地遍历当前节点的firstsubelement域所指的子树;
递归地遍历当前节点的nextsibling域所指的子树;
递归地遍历当前节点的nextrecord域所指的子树。
该算法的实现需借用两个栈s1、s2,s1用于依次存放结构树中的所有元素节点,s2用于存放s1的当前栈顶节点的所有属性。对于越复杂的查询,其结构树的嵌套层次也越多,而在这种情况下重复记录的个数也越少,同时也往往位于树的更深层,因此对所需空间影响最大的是树的元素嵌套层次和每层的子元素个数。
三、结束语
本文给出了一种异构数据集成系统中关系数据源包装器设计与实现的方法,很好地解决了XQuery查询到SQL查询的转换以及关系数据查询结果到XML格式数据的转换问题,为异构数据源的集成访问提供了有力的支持。
参考文献:
[1]World-Wide Web Consortium.XQuery 1.0:An XML Query Language,http://www.w3.org/TR/xquery/, W3C Working Draft,November 03,2005.
[2]Gerti Kappel,Elisabeth Kapsammer,and Werner Rets-chitzegger.Integrating XML and Relational Database Systems ACM SIGMOD 2004.
[3][美]Fabio Arciniegas 著.天宏工作室译.XML开发指南[M].北京:清华大学出版社,2003
关键词:关系数据 查询 转换 XML 包装器 设计
中图分类号:TP311文献标识码:A文章编号:1673-8454(2007)09-0021-03
一、引言
包装器是自治异构数据源集成系统中的重要组成部分,随着与XML有关的标准不断制定和完善,越来越多的数据被用XML表示,然而必须注意的一个事实是,目前和在一个可以预见的未来,大部分应用系统,甚至是新的基于Web的应用系统,仍然将关系数据库系统作为数据存储和查询的首选。关系数据库系统的可靠性、技术的成熟性、丰富的工具、高性能等,都决定了这一点。本文探讨在自治异构数据源集成系统情境下,如何将XQuery查询翻译成SQL查询,如何将关系数据转换为XML数据表示。[1]
1.查询转换器的设计
(1)将XQuery子查询重写成XML文档
当包装器接收到一个针对关系数据源的XQuery查询时,例如要查询订单号oid为1001的Yang Hui客户定购的图书,如图3所示。首先进行查询重写,将关系数据源上的子查询(XQuery形式)重写成查询XML文档,将被重写成如图4所示的XML文档。
在图4的XML文档中,“Queries”节点包括“Query”、“From”和“where”三个子节点,其中,“Query”子节点用于描述查询内容;“From”子节点表示查询的数据库表;“Where”子节点用于描述查询条件。该文档的含义是:查出订单号为1001的Yang Hui客户定购的图书(包括oid、user、address、bid、title、price),接下来,系统会将生成的查询XML文档转换成SQL语句,进行下一步处理。
(2)将查询XML文档转换成SQL语句
对于关系型数据库的数据源,可采用模板法来定义查询 XML文档与SQL语句之间的映射关系,采用基于DOM的Java解析器ProjectX来解析XML查询文档,提取出其中的查询内容,组织成 SQL语句。[3]
为了使系统可以很容易地将文档的元素和属性映射到其它数据结构或对象分级结构中,也为了在客户端的浏览器和服务器之间传输文件变得方便和可靠,便于XML文件被机器正确识别并理解文档的内容和含义,使得用户可以使用XML文件作为一种中介体让数据在不同的数据源或应用程序之间灵活地进行交换传输,我们需要对XML查询文档定义严格的文档模型DTD,规定各个标签的含义,以及与数据库全局视图中的各部分的一一对应关系。以图4的XML查询文档为例,其对应的文档模型DTD如下:[3]
<!DOCTYPE Query[
<!ELEMENT Query(Item+,From,Where*)>
<!ELEMENT Item(#PCDATA)>
<!ELEMENT From(#PCDATA)>
<!ELEMENT Where(fiel)>
<!ELEMENT fiel(#PCDATA)>
<!ATTLIST fiel name CDATA #REQUIRED>
]>
模板法要求定义固定的模板,因此对于关系型数据库、面向对象型数据库及其他形式的数据源,只要事先定义好对应该数据库查询语言的XML模板的DTD,就能让应用程序识别并转化XML子查询。
在集成系统中,发送给关系数据源的XML查询文档如图4所示。查询转换器将该XML查询文档转换为如下的SQL语句:
SELECT oid,user,address,bid,title,price
FROM order,book
WHERE user=’Yang Hui’ and oid=’1001’
(3)实现策略
//使用IBM XML4JApache Xerces创建一个DOM解析器
import org.apache.xerces.parsers.DOMParser;
DOMParser parser=new DOMParser();
//解析一个XML文档,生成一棵DOM树
try{
DOMParser parser=new DOMParser();
Parser.parse(filename);
Document doc=parser.getDocument();
}
//输出节点的子节点
NodeList children=node.getchildNodes();
If(children!=null){
Int len=children.getLength();
For(int i=0;i
}
//定义一个字符串变量sql来存储SQL语句
String sql=“SELECT ”;
//取出各个查询项
For(int i=0;i
if(children.item(i).getNodeName().equalsIgnoreCase(“Item”)==ture)
sql=sql children.item(i).getNodeValue() “,”;
//找到From节点,组成SQL语句中的FROM部分
if(children.item(i).getNodeName().equalsIgnoreCase(“From”)==ture){
sql=sql.getSubString(0,sql.getlength()-1) “ FROM ”;
sql=sql children.item(i).getNodeValue() “,”;
}
//找到Where节点,组成SQL语句中的WHERE部分
if(children.item(i).getNodeName().equalsIgnoreCase(“Where”)==ture){
sql=sql “ WHERE ”;
for(int j=0;j
sql=sql fiel.getAttributes() “=”;
sql=sql fiel.getFirstChild().getNodeValue() “ and ”;
}
sql=sql.getSubString(0,sql.getLength()-3);
}
2.结果产生器的设计
(1)关系模式映射为XML Schema
结果产生器是数据源包装器的一部分,它需要完成的主要功能是将从关系数据源得到的查询结果记录映射成XML格式。
关系数据模型具有“表”结构表示、扁平和规范化的特点。相反,XML数据却具有任意层次的嵌套结构和非规范化的特点,良好地表示二者数据之间的映射关系是数据格式转换的起点。XML语言本身的灵活性为我们找到问题的答案提供了可能。以下是从关系数据库的关系模式映射为XML Schema的方法步骤。
1)获取关系表的所有信息;2)用恰当的XML命名空间和目标模式空间信息创建一个模式标签;3)建立对根元素的描述;4)建立对表的描述;5)建立对记录元素的描述;6)建立对字段元素的描述;7)数据类型的描述。
运用上述模式转换的方法,结果产生器可以将关系模式转换成XML Schema文档。
(2)基于查询的映射
基于查询的转换方法一般都是基于上面讨论的简单映射,但由于在实现中有查询和加标记这两大处理,因而有先查询后加标记和先加标记后查询这两类不同的方法。如果先对完整的关系数据库进行转换,当表的数目和表中的字段数都较多时,时间性能将大大下降,代价过高。因而,我们使用的方法是先对关系数据库进行查询,将查询结果以视图的形式组织,得到较小的数据集,然后再对视图进行映射转换。
针对XML文档是树形结构的特点,我们提出一种基于树的方法。该方法的原理是先构造出复杂查询的结果视图;将该结果视图看成一个单一的表,然后将其映射为Schema;再根据Schema为该结构建立一棵树;将查询结果插入到树中合适的位置上;按深度优先、先根遍历的方法遍历该树,即可得到目标XML文档。
对于关系数据源上的查询,为了得到目标XML文档,可先利用SQL创建该文档的关系视图,根据该视图按照上面的映射规则可得相应的Schema;根据Schema建立一棵用于表示该数据模式的树。下面是对这样的一棵树进行深度优先、先根遍历的算法(以自然语言的形式给出):
traversal(p:treepoint);
访问根节点;
访问根节点的所有属性节点;
递归地遍历根节点的firstsubelement域所指的树;
其中对根节点以下的各级元素节点,遍历的算法为:
访问当前节点;
访问当前节点的所有属性节点;
递归地遍历当前节点的firstsubelement域所指的子树;
递归地遍历当前节点的nextsibling域所指的子树;
递归地遍历当前节点的nextrecord域所指的子树。
该算法的实现需借用两个栈s1、s2,s1用于依次存放结构树中的所有元素节点,s2用于存放s1的当前栈顶节点的所有属性。对于越复杂的查询,其结构树的嵌套层次也越多,而在这种情况下重复记录的个数也越少,同时也往往位于树的更深层,因此对所需空间影响最大的是树的元素嵌套层次和每层的子元素个数。
三、结束语
本文给出了一种异构数据集成系统中关系数据源包装器设计与实现的方法,很好地解决了XQuery查询到SQL查询的转换以及关系数据查询结果到XML格式数据的转换问题,为异构数据源的集成访问提供了有力的支持。
参考文献:
[1]World-Wide Web Consortium.XQuery 1.0:An XML Query Language,http://www.w3.org/TR/xquery/, W3C Working Draft,November 03,2005.
[2]Gerti Kappel,Elisabeth Kapsammer,and Werner Rets-chitzegger.Integrating XML and Relational Database Systems ACM SIGMOD 2004.
[3][美]Fabio Arciniegas 著.天宏工作室译.XML开发指南[M].北京:清华大学出版社,2003