基于XML的數(shù)據(jù)庫(kù)總體分析(上)
為什么要把XML和數(shù)據(jù)庫(kù)相聯(lián)系呢?舉個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題,比如你有一個(gè)電子商務(wù)的應(yīng)用程序需要使用XML來(lái)進(jìn)行數(shù)據(jù)傳輸。你所關(guān)心的是數(shù)據(jù)本身應(yīng)該具有的結(jié)構(gòu),你并不關(guān)心它在文檔中實(shí)際的存儲(chǔ)結(jié)構(gòu)。如果你的應(yīng)用程序很簡(jiǎn)單的話,基本的文件系統(tǒng)將滿足你的需求,但如果應(yīng)用本身很復(fù)雜的話,你就需要一個(gè)完整的開(kāi)發(fā)應(yīng)用環(huán)境來(lái)支持XML。從另一個(gè)方面來(lái)說(shuō),假設(shè)你有一個(gè)Web站點(diǎn),它的內(nèi)容是由一系列XML文檔構(gòu)成的,你不僅要管理這個(gè)站點(diǎn),同時(shí)你需要提供給用戶一個(gè)搜索該站點(diǎn)內(nèi)容的機(jī)制。而這些都需要借助數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)。
選擇一個(gè)數(shù)據(jù)庫(kù)的最重要的因素是你是否需要數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)數(shù)據(jù)或者是文檔,如果你想要存儲(chǔ)數(shù)據(jù)的話,你需要一個(gè)關(guān)系數(shù)據(jù)庫(kù)或者是對(duì)象數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)實(shí)際的數(shù)據(jù),同時(shí)你需要中間件在數(shù)據(jù)庫(kù)和XML文檔之間建立橋梁關(guān)系,從另一方面來(lái)說(shuō),如果你想要存儲(chǔ)文檔,你需要一個(gè)內(nèi)容管理系統(tǒng),通過(guò)它進(jìn)行文檔的存儲(chǔ)。實(shí)際上,XML文檔可以分到兩大類:以數(shù)據(jù)為中心或者以文檔為中心。
以數(shù)據(jù)為中心的文檔:數(shù)據(jù)為中心的文檔有非常規(guī)則的結(jié)果,比如關(guān)于銷售訂單或者是飯店菜單的XML文檔。以數(shù)據(jù)為中心的文檔通常是為機(jī)器設(shè)計(jì)的,也就是說(shuō)主要是方便機(jī)器進(jìn)行處理。通常,任何Web站點(diǎn)可以動(dòng)態(tài)的構(gòu)建HTML文檔,其步驟如下,根據(jù)用戶的查詢請(qǐng)求找到相關(guān)的面向數(shù)據(jù)的XML文檔,然后通過(guò)XSL對(duì)XML文檔進(jìn)行轉(zhuǎn)化,讓基于HTML的瀏覽器能夠方便的瀏覽結(jié)果。
以文檔為中心的文檔:以文檔為中心的文檔具有不規(guī)則的結(jié)構(gòu),而且數(shù)據(jù)的粒度也比較大。具體的例子如書(shū)本、電子郵件、廣告等等。以文檔為中心的文檔主要是用人類而設(shè)計(jì)的。
為了存儲(chǔ)或提取數(shù)據(jù),你可以使用數(shù)據(jù)庫(kù)和中間件,或者你可以使用XML服務(wù)器,或者是基于XML的Web服務(wù)器。為了存儲(chǔ)文檔,你需要一個(gè)內(nèi)容管理系統(tǒng)或者是可持久化的DOM實(shí)現(xiàn)。可以在數(shù)據(jù)庫(kù)或者是XML文檔中發(fā)現(xiàn)大量基于數(shù)據(jù)為中心的文檔。這樣我們就需要工具把數(shù)據(jù)從數(shù)據(jù)庫(kù)轉(zhuǎn)化成XML文檔,或者把一個(gè)XML文檔轉(zhuǎn)換到數(shù)據(jù)庫(kù)中。同時(shí)需要注意的是,當(dāng)把數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中的時(shí)候,需要拋棄一個(gè)文檔的很多信息,比如它的名稱和DTD,它的物理結(jié)構(gòu),比如實(shí)體定義和使用,一個(gè)節(jié)點(diǎn)下元素的位置排列,二進(jìn)制數(shù)據(jù)的存儲(chǔ)方式等等。同樣,當(dāng)從數(shù)據(jù)庫(kù)中提取數(shù)據(jù)的時(shí)候,產(chǎn)生的XML文檔通常不包含CDATA或者是實(shí)體使用的說(shuō)明,而且節(jié)點(diǎn)下元素的排列位置只和數(shù)據(jù)庫(kù)中記錄的順序位置一致。實(shí)際上一個(gè)XML文檔存儲(chǔ)到數(shù)據(jù)庫(kù)中,再由該數(shù)據(jù)庫(kù)生成此XML文檔,這前后兩個(gè)文檔格式幾乎不可能完全一樣。
為了在數(shù)據(jù)庫(kù)和XML文檔之間傳遞數(shù)據(jù),必須在文檔結(jié)構(gòu)和數(shù)據(jù)庫(kù)結(jié)構(gòu)之間建立映射,這種映射可以有兩個(gè)分類:模板驅(qū)動(dòng)和模型驅(qū)動(dòng)。
1.基于模板驅(qū)動(dòng)的映射:需要在一個(gè)模板中嵌入命令,并用數(shù)據(jù)傳輸中間件進(jìn)行處理。比如,考慮下面的模板:
- <?xml version="1.0"?>
- <FlightInfo>
- <Intro>The following flights have available seats:</Intro>
- <SelectStmt>SELECT Airline, FltNumber, Depart, Arrive FROM Flights</SelectStmt>
- <Conclude>W(wǎng)e hope one of these meets your needs</Conclude>
- </FlightInfo>
注意其中嵌入了一個(gè)SELECT語(yǔ)句。當(dāng)用數(shù)據(jù)傳輸中間件進(jìn)行處理的時(shí)候,每一個(gè)SELECT語(yǔ)句都會(huì)被它的結(jié)果所代替,用XML格式化形式表現(xiàn)為:
- <?xml version="1.0"?>
- <FlightInfo>
- <Intro>The following flights have available seats:</Intro>
- <Flights>
- <Row>
- <Airline>ACME</Airline>
- <FltNumber>123</FltNumber>
- <Depart>Dec 12, 1998 13:43</Depart>
- <Arrive>Dec 13, 1998 01:21</Arrive>
- </Row>
- ...
- </Flights>
- <Conclude>W(wǎng)e hope one of these meets your needs</Conclude>
- </FlightInfo>
基于模板驅(qū)動(dòng)的映射可以是相當(dāng)靈活的,比如,一些產(chǎn)品允許你把結(jié)果集放到XML文檔的任何位置,同時(shí)可以對(duì)SELECT語(yǔ)句設(shè)置參數(shù),并且可以使用for循環(huán)語(yǔ)句和if條件語(yǔ)句等。值得注意的是,當(dāng)前基于模板驅(qū)動(dòng)的映射只能應(yīng)用于在關(guān)系數(shù)據(jù)庫(kù)和XML文檔之間傳遞數(shù)據(jù)。
基于模型驅(qū)動(dòng)的映射:也就是說(shuō)把數(shù)據(jù)從數(shù)據(jù)庫(kù)傳送到XML文檔是用一個(gè)具體的模型實(shí)現(xiàn)的,這樣,XSL可以被結(jié)合到基于模型映射的產(chǎn)品上。在XML文檔中,兩種模型是很常見(jiàn)的:表格模型(table model)和數(shù)據(jù)專用對(duì)象模型(data-specific object model)。
2.表格模型:許多中間件軟件包用表格模型在XML文檔和關(guān)系數(shù)據(jù)庫(kù)之間傳遞數(shù)據(jù)。它把XML文檔表示為一個(gè)單一的表格或者是表格的集合。這樣,一個(gè)XML文檔的結(jié)構(gòu)可以用如下的形式表示:
- <database>
- <table>
- <row>
- <column1>...</column1>
- <column2>...</column2>
- ...
- </row>
- ...
- </table>
- ...
- </database>
這里關(guān)鍵字"talbe"在把數(shù)據(jù)從數(shù)據(jù)庫(kù)傳遞到XML文檔的時(shí)候,表示一個(gè)單一的結(jié)果集,把數(shù)據(jù)從XML文檔傳遞到數(shù)據(jù)庫(kù)的時(shí)候,表示表示一個(gè)單一的表格或者視圖。但是,當(dāng)結(jié)果集合不只一個(gè)的時(shí)候,或者當(dāng)XML文檔包括多個(gè)復(fù)雜嵌套的時(shí)候,這種傳遞方式就不能適應(yīng)了。
3.數(shù)據(jù)專用的對(duì)象模型:把一個(gè)XML文檔表示為由數(shù)據(jù)對(duì)象構(gòu)成的樹(shù),每一個(gè)元素類型和對(duì)象相對(duì)應(yīng)。主要在面向?qū)ο蠛蛯哟螖?shù)據(jù)庫(kù)中使用,通過(guò)傳統(tǒng)的關(guān)系-對(duì)象模型也可以映射到關(guān)系數(shù)據(jù)庫(kù)中。注意這種模型并不是文檔對(duì)象模型(DOM)。比如,銷售訂單文檔可以被看成一個(gè)對(duì)象樹(shù),其中包括五個(gè)類:Orders, SalesOrder, Customer, Line, 和Part。如下所示:
當(dāng)把一個(gè)XML文檔看成是一個(gè)以數(shù)據(jù)為中心的對(duì)象樹(shù)的時(shí)候,元素不一定和對(duì)象相對(duì)應(yīng),比如,一個(gè)元素只包含PCDATA,它能夠被當(dāng)成一個(gè)屬性,它包括一個(gè)單一的,標(biāo)量值。
實(shí)際上在XML和數(shù)據(jù)庫(kù)之間進(jìn)行數(shù)據(jù)轉(zhuǎn)化的時(shí)候,需要考慮兩個(gè)過(guò)程:一個(gè)是從數(shù)據(jù)庫(kù)模式中產(chǎn)生DTD,另外一個(gè)是根據(jù)DTD生成數(shù)據(jù)庫(kù)模式
從一個(gè)DTD中生成一個(gè)關(guān)系模式的步驟如下:
1. 對(duì)每一個(gè)元素,產(chǎn)生一個(gè)表和一個(gè)主鍵列。
2. 對(duì)每一個(gè)有混合內(nèi)容的元素,產(chǎn)生一個(gè)獨(dú)立的表格,用來(lái)存儲(chǔ)PCDATA,并通過(guò)父表的主鍵和父表相聯(lián)。
3. 對(duì)元素類型中的每一個(gè)單一值的屬性,對(duì)具有只有PCDATA內(nèi)容的子元素(該子元素按順序出現(xiàn)),產(chǎn)生一個(gè)單獨(dú)的列,如果子元素類型或者值是可以選擇的話,該列就應(yīng)該可以允許為NULL類型。
4. 對(duì)有多個(gè)值的屬性和可以出現(xiàn)多次的子元素(該子元素PCDATA)的話,需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的表來(lái)存儲(chǔ)這些值,并通過(guò)父表的主鍵和父表相聯(lián)。
5. 對(duì)每一個(gè)包含元素或者混合內(nèi)容的子元素來(lái)說(shuō),通過(guò)父表的主鍵把父元素和子元素聯(lián)接起來(lái)。
從一個(gè)關(guān)系數(shù)據(jù)庫(kù)模式構(gòu)建DTD步驟如下:
1. 對(duì)每一個(gè)表,創(chuàng)建一個(gè)元素。
2. 對(duì)表中的每一列,創(chuàng)建一個(gè)屬性或者是一個(gè)只有PCDATA 內(nèi)容的子元素。
3. 根據(jù)表中的每一主鍵/外鍵關(guān)系,創(chuàng)建該表元素的子元素。
本文就介紹到這里,更多的內(nèi)容我們會(huì)在下節(jié)中繼續(xù)介紹。
【編輯推薦】