Storing XML in Relational Databases(2)
?Storing XML in Relational Databases(2)
From http://www.xml.com
IBM DB2 XML 擴(kuò)展
SQL 到 XML 的映射
在用DB2作為XML存儲(chǔ)庫(kù)時(shí),IBM的XML擴(kuò)展提供了兩種訪問和存儲(chǔ)的方法:
1.??????? XML列:從一個(gè)列中存儲(chǔ)和得到整個(gè)XML文檔。
2.??????? XML集合:把XML文檔分解成一系列的關(guān)系表,或者從一系列的關(guān)系表中重組成一個(gè)XML文檔。
DTDs存儲(chǔ)在DTD 庫(kù)中,在DB2中是一個(gè)被稱為DTD_REF 的表。它的模式名稱叫“db2xml“。每個(gè)在DTD_REF中的DTD都有一個(gè)唯一的標(biāo)識(shí)ID,數(shù)據(jù)表和XML文檔結(jié)構(gòu)之間的映射被一個(gè)數(shù)據(jù)訪問定義(DAD)文件進(jìn)行定義,DAT引用一個(gè)處理過的文檔DTD,因此它在XML文檔,此文檔的DTD和映射至數(shù)據(jù)庫(kù)表的規(guī)則之間提供了一個(gè)橋梁。
以下是一個(gè)DAD的例子:
<?xml version="1.0"?>
<!DOCTYPE??? DAD??? SYSTEM??? "dad.dtd">???
<DAD>???
??? <dtdid>FXTRADE.DTD</dtdid>???
??? <validation>YES</validation>???
??? <Xcollection>???
??????? <prolog>?xml version="1.0"?</prolog>???
??????? <doctype>!DOCTYPE???? FXTRADE?????? FXTRADE.DTD </doctype>???
??????? <root_node>???
?? <element_node???? name="FXTRADE">???
?????? <RDB_node>???
?????????? <table name="FXTRADE"/>???
?????????? <table name="ACCOUNT" key="ID"/> ???
?????????? <condition>???
????? FXTRADE.ACCOUNT=ACCOUNT.ID???
?????????? </condition>???
?????? </RDB_node>???
?????? <element_node name="CURRENCY1">???
?????????????? <text_node>???
?????????? <RDB_node>???
???????????????? <table name="FXTRADE"/>???
???????????????? <column name="CURRENCY1" type="CHAR(3)"/>???
?????????? </RDB_node>???
??????????????? </text_node>
?????? </element_node>
?????? <element_node name="CURRENCY2">
?????????????? <text_node>
?????????? <RDB_node>
???????????????? <table name="FXTRADE"/>
???????????????? <column name="CURRENCY2" type="CHAR(3)"/>
?????????? </RDB_node>
????????????? </text_node>
?????? </element_node>
?????? <element_node name="AMOUNT">
?????????????? <text_node>
?????????? <RDB_node>
??????????????? ?<table name="FXTRADE"/>
???????????????? <column name="AMOUNT" type="DECIMAL(18,2)"/>
?????????? </RDB_node>
?????????????? </text_node>
?????? </element_node>
?????? <element_node name="SETTLEMENT">
???????????? <text_node>
?????????? <RDB_node>
??????? ?????????<table name="FXTRADE"/>
???????????????? <column name="SETTLEMENT" type="DATE"/>
?????????? </RDB_node>
????????????? </text_node>
?????? </element_node>
?????? <element_node name="ACCOUNT">
?????????? <element_node name="BANKCODE">
???????????? ??<text_node>
?????????????????? <RDB_node>
?????????????????????? <table name="ACCOUNT"/>
?????????????????????? <column name="BANKCODE"
?????????????????????????? type="VARCHAR(100)"/>
?????????????????? </RDB_node>
?????????????? </text_node>
????????? ?</element_node>
?????????? <element_node name="BANKACCT">
?????????????? <text_node>
?????????????????? <RDB_node>
??????????????????????? <table name="ACCOUNT"/>
??????????????????????? <column name="BANKACCT"
??????????????????????????? type="VARCHAR(100)"/>
??????????????????? </RDB_node>
?????????????? </text_node>
?????????? </element_node>
?????? </element_node> <!--end of? Account element-->
?? </element_node>??? <!-- end of? FxTrade element -->
??????? </root_node>
??? </Xcollection>
</DAD>
?
?
?
DAD通過element_node(元素結(jié)點(diǎn)) 到RDB_node(關(guān)系數(shù)據(jù)庫(kù)結(jié)點(diǎn))的關(guān)聯(lián)定義了XML元素和關(guān)系數(shù)據(jù)庫(kù)列之間的映象。頂層的元素結(jié)點(diǎn)FXTRADE 作為表FXTRADE 和?????? ACCOUNT之間的一個(gè)關(guān)聯(lián)被定義。ACCOUNT擁有一個(gè)ID列作為主鍵。子元素 CURRENCY1映射為表FXTADEK 表中的字段CURRENCY1,其它的類似。?
?
?
?
Microsoft SQL Server 2000
SQL到XML的映射
SQL Server的雙向映射規(guī)則均應(yīng)用了不同的語(yǔ)法,下面將會(huì)講述相關(guān)的細(xì)節(jié)。
從數(shù)據(jù)庫(kù)中提取XML文檔
數(shù)據(jù)庫(kù)列和XML元素或?qū)傩灾g的映射是用SELECT語(yǔ)句中的AS別名來(lái)定義的:
<database column> AS [Element Name! Nesting Level! Attribute Name! Directive]
文檔的最頂層被指定為一級(jí),如下面所示。默認(rèn)的,列均被映射成為屬性,指示“element”可以改變默認(rèn)的設(shè)置。
從數(shù)據(jù)庫(kù)數(shù)據(jù)產(chǎn)生XML文檔的處理過程分兩步:
1.???????? 為輸出XML文檔的元子元素創(chuàng)建AS-aliases。別名定義了元素間的父子關(guān)系,下面是為我們的樣例文檔定義的別名:
FXTRADE?????? /* LEVEL=1 */???
??? CURRENCY1?? [FXTRADE!1!CURRENCY1]???
??? CURRENCY2?? [FXTRADE!1!CURRENCY2]???
??? AMOUNT????? [FXTRADE!1!AMOUNT]???
??? SETTLEMENT? [FXTRADE!1!SETTLEMENT]???
??? ACCOUNT?? /* LEVEL=2? */???
??????? BANKCODE???? [ACCOUNT!2!BANKCODE]???
??????? BANKACCT???? [ACCOUNT!2!BANKACCT]??
2.???????? 在SQL中定義輸出樹的結(jié)構(gòu),樹的每一層均用一個(gè)SQL語(yǔ)句來(lái)定義,然后通過UNION聯(lián)合所有的SQL語(yǔ)句來(lái)整合樹中所有的層。Level-1 SELECT語(yǔ)句先定義了其它層上所有原子元素的名字,每個(gè)SELECT語(yǔ)句都有一層標(biāo)記和它的父標(biāo)記,對(duì)應(yīng)于對(duì)樹的根,在結(jié)果集中有一條記錄,如下第一條SELECT語(yǔ)句:
SELECT???
??? 1????????? AS??? Tag,???
??? NULL?????? AS??? Parent,???
??? NULL?????? AS??? [FXTRADE!1!CURRENCY1],???
??? NULL?????? AS??? [FXTRADE!1!CURRENCY2],???
??? NULL?????? AS??? [FXTRADE!1!AMOUNT],???
??? NULL?????? AS??? [FXTRADE!1!SETTLEMENT],???
??? NULL?????? AS ???[ACCOUNT!2!BANKCODE],???
??? NULL?????? AS??? [ACCOUNT!2!BANKACCT]???
FROM???????????
??? FXTRADE???
UNION ALL???
SELECT???
??? 2,???
??? 1,???
??? FXTRADE.CURRENCY1,???
??? FXTRADE.CURRENCY2,???
??? FXTRADE.AMOUNT,???
??? FXTRADE.SETTLEMENT,???
??? ACCOUNT.BANKCODE,???
??? ACCOUNT.BANKACCT???
FROM???
??? FXTRADE,??? ACCOUNT???
WHERE???
??? FXTRADE.ACCOUNT = ACCOUNT.ID???
ORDER??? BY??? [ACCOUNT!2!BANKCODE],???
??????? [ACCOUNT!2!BANKACCT]???
FOR??? XML??? EXPLICIT, ELEMENTS?
FOR XML通過分析標(biāo)記和在行集的AS別名來(lái)構(gòu)造XML文檔,關(guān)鍵字EXPLICIT選擇更有彈性的用戶自定義模式來(lái)構(gòu)造XML文檔,而AUTO模式則根據(jù)默認(rèn)的規(guī)則來(lái)構(gòu)造XML文檔。關(guān)鍵字ELEMENTS把SQL的中的列模擬為元素,否則,默認(rèn)是把列模擬為屬性。
?
用數(shù)據(jù)庫(kù)存儲(chǔ)XML
用OPENXML來(lái)存儲(chǔ)XML文檔,一個(gè)行集的新功能,類似于表或視圖,OPENXML可用于插入或更新,或作為SELECT INTO 的目標(biāo)表,其簡(jiǎn)單語(yǔ)法如下:
OPENXML??? (<XML document handler>, <path pattern>, <flags>)???
WITH???? (Schema | Table)
存儲(chǔ)XML文檔的過程分以下三步:
1.? 通用解析XML文檔為DOM獲得其句柄,這可以使用存儲(chǔ)過程sp_xml_preparedocument。
2.? 通過關(guān)聯(lián)模式中的字段和原子元素來(lái)創(chuàng)建模式。
XML元素的定義是通過一個(gè)路徑模式(絕對(duì)基路徑)加上一個(gè)相對(duì)元素路徑。以元素為中心的映射用標(biāo)專值2來(lái)指明。現(xiàn)存的表可用于替代模式,字段名和XML名字對(duì)應(yīng)。]
3.? 用存儲(chǔ)過程sq_xml_removedocument把解析過的XML文檔從內(nèi)存中移除。
下面是一個(gè)例子:
DECLARE @idoc int???
DECLARE @doc varchar(1000)???
SET @doc ='???
<FXTRADE>???
??? <CURRENCY1>GBP</CURRENCY1>???
??? <CURRENCY2>JPY</CURRENCY2>???
??? <AMOUNT>10000</AMOUNT>???
??? <SETTLEMENT>20010325</SETTLEMENT>???
??? <ACCOUNT>?? ?
??????? <BANKCODE>812</BANKCODE>???
??????? <BANKACCT>00365888</BANKACCT>???
??? </ACCOUNT>???
</FXTRADE>'???
-- Create internal DOM representation of the XML document.???
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc???
-- Execute a SELECT statement using OPENXML row set provider.???
SELECT *???
FROM OPENXML (@idoc, '/FXTRADE/ACCOUNT', 2)???
WITH (???
? CURRENCY1???? CHAR (3),?????? '../@CURRENCY1',???
? CURRENCY2???? CHAR (3),?????? '../@CURRENCY2',???
? AMOUNT??????? NUMERIC (18,2), '../@AMOUNT',???
? SETTLEMENT??? DATETIME,?????? '../@SETTLEMENT',???
? BANKCODE????? VARCHAR (100),? '@BANKCODE',???
? BANKACCT????? VARCHAR (100),? '@BANKACCT' )
EXEC sp_xml_removedocument @idoc???
?
總結(jié)
用Microsoft SQL Server 2000,提取和存儲(chǔ)XML文檔并不是用對(duì)稱的語(yǔ)法,提取用的是擴(kuò)展SELECT子句FOR XML。存儲(chǔ)XML則是引進(jìn)了行集功能OPENXML,類似于表或視圖,提取映射規(guī)則是基于:A)為特定的樹層次引進(jìn)標(biāo)記,B)為表中的字段和XML文檔元素的父子關(guān)系建立關(guān)聯(lián)。存儲(chǔ)XML是把XML文檔重建為簡(jiǎn)單的模式或表,“字段-元素”關(guān)聯(lián)是用XPATH表達(dá)式來(lái)定義的。
?
SYSBASE ADAPTIVE SERVER
SQL to XML映射
SYBASE 利用一個(gè)XML文檔類型ResultSet來(lái)描述XML文檔的元數(shù)據(jù)(如元素名,類型,大小等)和實(shí)際的行數(shù)據(jù),下面是假想FxTradeSet.xml文檔的摘錄:
<?xml version="1.0"?>???
<!DOCTYPE ResultSet SYSTEM "ResultSet.dtd">???
<ResultSet>???
??? <ResultSetMetaData>???
??????? <ColumnMetaData???
??????? ...
??????? getColumnLabel="CURRENCY1"???
??????? getColumnName="CURRENCY1"???
??????? getColumnType="12"???
???????? ... />???
?? ...???
?? </ResultSetMetaData>???
?? <ResultSetData>???
??????? <Row>???
?????????? <Column name="CURRENCY1">GBP</Column>???
??????? ...???
??????? </Row>???
??? </ResultSetData>???
</ResultSet>???
ResultSet的DTD不允許對(duì)嵌套元素的定義。
?
從數(shù)據(jù)庫(kù)中抽取XML
JAVA類ResultSetXml有一個(gè)構(gòu)造函數(shù),它以一個(gè)SQL查詢作為參數(shù),然后getXmlLText方法從結(jié)果集中抽取XML文檔:
jcs.xml.resultset.ResultSetXml???? rsx = new jcs.xml.resultset.ResultSetXml???
?????????? ("Select * from FxTrade", <other parameters>);???
FileUtil.string2File ("FxTradeSet.xml", rsx.getXmlText());???
?
用數(shù)據(jù)庫(kù)存儲(chǔ)XML
JAVA類ResultSetXml也可以用XML文檔作為其構(gòu)造函數(shù)據(jù)的參數(shù),然后toSqlScript方法會(huì)產(chǎn)生一個(gè)序列的SQL語(yǔ)句來(lái)對(duì)特定的表進(jìn)行插入或更新操作。
String??? xmlString = FileUtil.file2string ("FxTradeSet.xml");???
jcs.xml.resultset.ResultSetXml???? rsx = new jcs.xml.resultset.ResultSetXml???
?????????? (xmlString);???
String???? sqlString? = rsx.toSqlScript ("FxTrade", <other parameters>)???
?
總結(jié)
在這里,抽取和存儲(chǔ)XML文檔本質(zhì)上是對(duì)稱的,存儲(chǔ)不允許修改一個(gè)以上的表,抽取則把一個(gè)SQL查詢的結(jié)果轉(zhuǎn)換成一個(gè)簡(jiǎn)單結(jié)構(gòu)的文檔。
?
各供應(yīng)商的對(duì)比:
| 供應(yīng)商 | 映射規(guī)則 | 單表/多表 | 轉(zhuǎn)換方法 | 對(duì)稱抽取/存儲(chǔ) |
| Oracle | 在構(gòu)造關(guān)系對(duì)象數(shù)據(jù) 模型中指明 | 多表 | 有相應(yīng)的JAVA類 | 如果XML文檔和關(guān)系 對(duì)象模型匹配的話是對(duì)稱的 |
| IBM | DAD(數(shù)據(jù)訪問定義文件 | 多表 | 內(nèi)置的存儲(chǔ)過程 | 對(duì)稱 |
| Microsoft | SQL擴(kuò)展,行集功能 | 抽取是多表,存儲(chǔ)是單表 | 用SQL語(yǔ)句 FOR XML和行集OPENXML | 不對(duì)稱 |
| Sysbase | 結(jié)果集的DTD | 單表,但查詢可以包含多表 | 相應(yīng)的JAVA類 | 對(duì)稱 |
| ? | ? | ? | ? | ? |
?
供應(yīng)商共同的特點(diǎn):
1.? XML的持續(xù)化都有一個(gè)特定的原則,也就是說,對(duì)任意的XML文檔存儲(chǔ)并沒有普便的方法。
2.? 存儲(chǔ)時(shí)均需要對(duì)XML文檔進(jìn)行預(yù)處理,比如把數(shù)字/日期變換成本地格式等,XSLT可以用于這種處理過程。
?
總結(jié)
以上是生活随笔為你收集整理的Storing XML in Relational Databases(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: why different people
- 下一篇: 在SunOS5.8/solaris7上使