Storing XML in Relational Databases(2)
?Storing XML in Relational Databases(2)
From http://www.xml.com
IBM DB2 XML 擴展
SQL 到 XML 的映射
在用DB2作為XML存儲庫時,IBM的XML擴展提供了兩種訪問和存儲的方法:
1.??????? XML列:從一個列中存儲和得到整個XML文檔。
2.??????? XML集合:把XML文檔分解成一系列的關系表,或者從一系列的關系表中重組成一個XML文檔。
DTDs存儲在DTD 庫中,在DB2中是一個被稱為DTD_REF 的表。它的模式名稱叫“db2xml“。每個在DTD_REF中的DTD都有一個唯一的標識ID,數據表和XML文檔結構之間的映射被一個數據訪問定義(DAD)文件進行定義,DAT引用一個處理過的文檔DTD,因此它在XML文檔,此文檔的DTD和映射至數據庫表的規則之間提供了一個橋梁。
以下是一個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(元素結點) 到RDB_node(關系數據庫結點)的關聯定義了XML元素和關系數據庫列之間的映象。頂層的元素結點FXTRADE 作為表FXTRADE 和?????? ACCOUNT之間的一個關聯被定義。ACCOUNT擁有一個ID列作為主鍵。子元素 CURRENCY1映射為表FXTADEK 表中的字段CURRENCY1,其它的類似。?
?
?
?
Microsoft SQL Server 2000
SQL到XML的映射
SQL Server的雙向映射規則均應用了不同的語法,下面將會講述相關的細節。
從數據庫中提取XML文檔
數據庫列和XML元素或屬性之間的映射是用SELECT語句中的AS別名來定義的:
<database column> AS [Element Name! Nesting Level! Attribute Name! Directive]
文檔的最頂層被指定為一級,如下面所示。默認的,列均被映射成為屬性,指示“element”可以改變默認的設置。
從數據庫數據產生XML文檔的處理過程分兩步:
1.???????? 為輸出XML文檔的元子元素創建AS-aliases。別名定義了元素間的父子關系,下面是為我們的樣例文檔定義的別名:
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中定義輸出樹的結構,樹的每一層均用一個SQL語句來定義,然后通過UNION聯合所有的SQL語句來整合樹中所有的層。Level-1 SELECT語句先定義了其它層上所有原子元素的名字,每個SELECT語句都有一層標記和它的父標記,對應于對樹的根,在結果集中有一條記錄,如下第一條SELECT語句:
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通過分析標記和在行集的AS別名來構造XML文檔,關鍵字EXPLICIT選擇更有彈性的用戶自定義模式來構造XML文檔,而AUTO模式則根據默認的規則來構造XML文檔。關鍵字ELEMENTS把SQL的中的列模擬為元素,否則,默認是把列模擬為屬性。
?
用數據庫存儲XML
用OPENXML來存儲XML文檔,一個行集的新功能,類似于表或視圖,OPENXML可用于插入或更新,或作為SELECT INTO 的目標表,其簡單語法如下:
OPENXML??? (<XML document handler>, <path pattern>, <flags>)???
WITH???? (Schema | Table)
存儲XML文檔的過程分以下三步:
1.? 通用解析XML文檔為DOM獲得其句柄,這可以使用存儲過程sp_xml_preparedocument。
2.? 通過關聯模式中的字段和原子元素來創建模式。
XML元素的定義是通過一個路徑模式(絕對基路徑)加上一個相對元素路徑。以元素為中心的映射用標專值2來指明?,F存的表可用于替代模式,字段名和XML名字對應。]
3.? 用存儲過程sq_xml_removedocument把解析過的XML文檔從內存中移除。
下面是一個例子:
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???
?
總結
用Microsoft SQL Server 2000,提取和存儲XML文檔并不是用對稱的語法,提取用的是擴展SELECT子句FOR XML。存儲XML則是引進了行集功能OPENXML,類似于表或視圖,提取映射規則是基于:A)為特定的樹層次引進標記,B)為表中的字段和XML文檔元素的父子關系建立關聯。存儲XML是把XML文檔重建為簡單的模式或表,“字段-元素”關聯是用XPATH表達式來定義的。
?
SYSBASE ADAPTIVE SERVER
SQL to XML映射
SYBASE 利用一個XML文檔類型ResultSet來描述XML文檔的元數據(如元素名,類型,大小等)和實際的行數據,下面是假想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不允許對嵌套元素的定義。
?
從數據庫中抽取XML
JAVA類ResultSetXml有一個構造函數,它以一個SQL查詢作為參數,然后getXmlLText方法從結果集中抽取XML文檔:
jcs.xml.resultset.ResultSetXml???? rsx = new jcs.xml.resultset.ResultSetXml???
?????????? ("Select * from FxTrade", <other parameters>);???
FileUtil.string2File ("FxTradeSet.xml", rsx.getXmlText());???
?
用數據庫存儲XML
JAVA類ResultSetXml也可以用XML文檔作為其構造函數據的參數,然后toSqlScript方法會產生一個序列的SQL語句來對特定的表進行插入或更新操作。
String??? xmlString = FileUtil.file2string ("FxTradeSet.xml");???
jcs.xml.resultset.ResultSetXml???? rsx = new jcs.xml.resultset.ResultSetXml???
?????????? (xmlString);???
String???? sqlString? = rsx.toSqlScript ("FxTrade", <other parameters>)???
?
總結
在這里,抽取和存儲XML文檔本質上是對稱的,存儲不允許修改一個以上的表,抽取則把一個SQL查詢的結果轉換成一個簡單結構的文檔。
?
各供應商的對比:
| 供應商 | 映射規則 | 單表/多表 | 轉換方法 | 對稱抽取/存儲 |
| Oracle | 在構造關系對象數據 模型中指明 | 多表 | 有相應的JAVA類 | 如果XML文檔和關系 對象模型匹配的話是對稱的 |
| IBM | DAD(數據訪問定義文件 | 多表 | 內置的存儲過程 | 對稱 |
| Microsoft | SQL擴展,行集功能 | 抽取是多表,存儲是單表 | 用SQL語句 FOR XML和行集OPENXML | 不對稱 |
| Sysbase | 結果集的DTD | 單表,但查詢可以包含多表 | 相應的JAVA類 | 對稱 |
| ? | ? | ? | ? | ? |
?
供應商共同的特點:
1.? XML的持續化都有一個特定的原則,也就是說,對任意的XML文檔存儲并沒有普便的方法。
2.? 存儲時均需要對XML文檔進行預處理,比如把數字/日期變換成本地格式等,XSLT可以用于這種處理過程。
?
總結
以上是生活随笔為你收集整理的Storing XML in Relational Databases(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: why different people
- 下一篇: 在SunOS5.8/solaris7上使