Storing XML in Relational Databases (1)

原创 2003年04月02日 08:59:00
 

Storing XML in Relational Databases (1)

From http://www.xml.com

translating by bjcfr

email:bjcfr@sohu.com

引言

有许多方法可以解决XML数据和关系数据库数据之间进行有效的相互转换的问题,数据库系统供应商如:IBM,微软,ORACLESYBASE等均开发了一些工具来帮助把XML文档转换成关系数据表,以下是几种不同的解决方案:

1.         ORACLE XML SQL UTILITY XML文档的诸多元素模拟成一些嵌套的表,相应的元素利用ORACLE OBJICT 数据类型来模拟。“SQL-TO-XML”的转换是通过数据表(referenced by Object datatype)和嵌套元素的一一对应关系来创建XML文档的。“XML-TO-SQL”的转换则需要对数据模型进行修改(把它从关系型转换为对象型)或者重建原始的XML文档。

2.         IBM DB2 XML 扩展允许把XML 文档作为类似于BLOB(二进制大对名象)的对象进行存储或把它们分解成一系列的表进行存储。后者的转换(known as XML collection)在XML 1.0的语法中被定义。

3.         微软通过扩展SQL-92和引进OPENXML行集来解决这个问题。

4.         SYSBASE ADAPTIVESERVER 引进了JAVA ResultSetXml作为这种双向转换处理的基础。

在本文中,我们为先分析一下这些供应商解决方案的细节,然后我们为试着加答下列问题:

           我们能否重新构造并简 个问题?

           在异构数据库环境下什么才是正确的解决方法?

下面的DTD是本文的所使用的范例:

<!-- Primitive Types -->
 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

<!ELEMENT CURRENCY1   (#PCDATA)>
<!ATTLIST CURRENCY1    e-dtype    NMTOKEN   #FIXED  "string"
                        e-dsize    NMTOKEN   #FIXED  "3">
 

<!ELEMENT CURRENCY2   (#PCDATA)>
<!ATTLIST CURRENCY2    e-dtype    NMTOKEN   #FIXED  "string"
                        e-dsize    NMTOKEN   #FIXED  "3">
 

<!ELEMENT AMOUNT      (#PCDATA)>
<!ATTLIST AMOUNT       e-dtype    NMTOKEN   #FIXED  "decimal">
 

<!ELEMENT SETTLEMENT  (#PCDATA)>
<!ATTLIST SETTLEMENT   e-dtype    NMTOKEN   #FIXED  "date">
 

<!ELEMENT BANKCODE    (#PCDATA)>
<!ATTLIST BANKCODE     e-dtype    NMTOKEN   #FIXED  "string">
 

<!ELEMENT BANKACCT    (#PCDATA)>
<!ATTLIST BANKACCT     e-dtype    NMTOKEN   #FIXED  "string">
 

<!-- Derived Types -->
 

<!ELEMENT ACCOUNT  (BANKCODE, BANKACCT)>
 

<!ELEMENT FXTRADE  (CURRENCY1, CURRENCY2, AMOUNT, SETTLEMENT, ACCOUNT)>
 

 

Oracle XML-SQL Utility (XSU)

SQL到XML的映射

ORACLE 把一系列的对象引用从数据库转化为XML元素的层次结构。表FXTRADE中的字段ACCOUNT用来作为类型AccountType对象引用的模拟。

 CREATE TABLE FXTRADE 

{

     CURRENCY1      CHAR (3),

     CURRENCY2      CHAR (3),

     AMOUNT         NUMERIC (18,2),

     SETTLEMENT     DATE,

     ACCOUNT        AccountType // object reference

}

 

CREATE TYPE AccountType as OBJECT

{  

     BANKCODE       VARCHAR (100),

     BANKACCT       VARCHAR (100) 

}

 

下面是从给定的对象-关系模型利用语句“SELECT * FROM FXTRADE”产生的相对应的XML文档:

<?xml version="1.0"?>

<ROWSET>

     <ROW num="1"> 

        <CURRENCY1>GBP</CURRENCY1>

        <CURRENCY2>JPY</CURRENCY2>

        <AMOUNT>10000</AMOUNT>

        <SETTLEMENT>20010325</SETTLEMENT>

        <ACCOUNT>

   <BANKCODE>812</BANKCODE>

   <BANKACCT>00365888</BANKACCT>

        </ACCOUNT>

    </ROW>

    <!-- additional rows ... -->

 </ROWSET>

 

从数据库中提取XML

下面的例子取自于ORACLE’s XSU 文档,把相应的SQL语句进行的替换并使用ORACLE的纯JAVA JDBC 瘦驱动程序。

首先,创建一个OracleXMLQuery的实例,然后执行一个查询,结果就是上面所提及的XML文档。相似地,XML文档也可以从DOM中被抽取,在这种情况下,应使用qry.getXMLDOM()而不是getXMLString().

import oracle.jdbc.driver.*;

import oracle.xml.sql.query.OracleXMLQuery;

import java.lang.*;

import java.sql.*;

 

// class to test XML document generation as String

class testXMLSQL {

 

   public static void main(String[] args)

   {

     try {

      // Create the connection

      Connection conn  = getConnection("scott","tiger");

 

      // Create the query class

      OracleXMLQuery qry = new OracleXMLQuery(conn,

         "SELECT  * FROM FXTRADE");

 

      // Get the XML string

      String str = qry.getXMLString();

 

      // Print the XML output

      System.out.println("The XML output is:/n"+str);

 

      // Always close the query to get rid of any resources..

      qry.close();

     } catch(SQLException e) {

      System.out.println(e.toString());

     }

   }

 

   // Get the connection given the user name and password.!

   private static Connection getConnection(String username,

        String password)

        throws SQLException

   {

      // register the JDBC driver..

       DriverManager.registerDriver(new 

          oracle.jdbc.driver.OracleDriver());

 

      // Create the connection using the OCI8 driver

       Connection conn =

        DriverManager.getConnection(

           "jdbc:oracle:thin:@dlsun489:1521:ORCL",

           username,password);

 

      return conn;

   }

}

 

Storing XML in the database

在这个例子中,用OracleXMLSave来把我们的XML文档存储为一个对象-关系模型insertXML方法用于插入数据。

import java.sql.*;

import oracle.xml.sql.dml.OracleXMLSave;

public class testXMLInsert

{

   public static void main(String args[])

             throws SQLException

  {

    Connection conn = getConnection("scott","tiger");

    OracleXMLSave sav = new OracleXMLSave(conn, "scott. FXTRADE");

  // Assume that the user passes in this document as 0-arg

      sav.insertXML(args[0]);

      sav.close();

   }

 

  ...

}

 

如果XML和数据库中的关系对象模型是同步的,但是如果不同步呢?这种情况下,通常有两种选择:

1.      调整关系对象模型,通过创建一个可更改的关系对象视图和完成多表的修改。

2.      可以把XML文档分解成一系列的简单的子文档。我们可以利用XSLT来过完成这个分解过程。

XSU不允许存储属性值,建议先把属性转换成元素再作处理。

Oracle XSU总结

一个XML到SQL的映射可以被一个关系对象模型进行模拟,其创建规则如下:

每一个嵌套的XML元素被映射为一个适当的对象引用。映射的规则已经内嵌在数据库模型上了。

相关的JAVA API包括OracleXMLQuery和 OracleXMLSave 两个类。(未待续完)

如果有人问你关系数据库的工作原理,叫他看这篇文章How does a relational database work

When it comes to relational databases, I can’t help thinking that something is missing. They’re used...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年05月11日 17:29
  • 1221

使用Jmeter登录WordPress的问题(Cookie管理)

1. 背景简介 最近在开始对Xen/KVM的嵌套虚拟化(nested virtualization)做一些性能测试并收集一些性能数据,以便证明各种特性(如virtual EPT、VMCS shado...
  • wanglha
  • wanglha
  • 2015年09月22日 10:45
  • 963

数据库应用之关系代数(relational algebra)

关系代数表达式的五个基本算子 1.选择(selection):即选择某些行。代码:select ··· from ··· where。表达式:σ()。 2.投影(projection):即选择...
  • u013816144
  • u013816144
  • 2015年11月23日 23:33
  • 2984

Android系统数据库

adb shell find / -name '*.db' -type f /mnt/sdcard/openfeint/webui/manifest.db /mnt/sdcard/...
  • knockheart
  • knockheart
  • 2013年07月09日 14:37
  • 1792

使用Jmeter登录WordPress的问题(Cookie管理)

1. 背景简介 最近在开始对Xen/KVM的嵌套虚拟化(nested virtualization)做一些性能测试并收集一些性能数据,以便证明各种特性(如virtual EPT、VMCS shado...
  • Elvis_lfc
  • Elvis_lfc
  • 2016年08月16日 15:42
  • 855

mysql的gtid参数了解

GTID简介 什么是GTID GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID实际上是由UUID+TID组成的。其中...
  • zhouhao88410234
  • zhouhao88410234
  • 2017年12月18日 15:19
  • 35

非关系型数据库NoSQL的崛起

非关系型数据库NoSQL的崛起 2012年12月06日15:45腾讯科技[微博]童云我要评论(0) 字号:T|T [导读]《连线》杂志对NoSQL的历史进行了追溯。介...
  • wangeven33
  • wangeven33
  • 2016年06月23日 18:58
  • 186

MongoDB分片实战(一):集群搭建

环境准备 Linux环境 主机 OS 备注 192.168.32.13 CentOS6.3 64位 普通PC 192.168.71.43 CentOS6.2 64位 ...
  • shmnh
  • shmnh
  • 2016年01月05日 22:55
  • 496

SQLite数据库存储

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了,因而特别适合在移动设备上使用。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事...
  • u014695188
  • u014695188
  • 2016年09月30日 10:28
  • 185

XML命名空间深度解析 —— XML1.0和XML1.1区别

在博客http://blog.csdn.net/ftomorrow/article/details/27102769中对XML命名空间进行了简单介绍,...
  • ftomorrow
  • ftomorrow
  • 2014年05月28日 18:04
  • 1176
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Storing XML in Relational Databases (1)
举报原因:
原因补充:

(最多只允许输入30个字)