1. 介紹 許多人認(rèn)為面向?qū)ο蟾拍詈完P(guān)系型數(shù)據(jù)庫相互不一致,并且不能結(jié)合。事實上完全相反!經(jīng)過靈活的使用,一個關(guān)系型數(shù)據(jù)庫能夠為面向?qū)ο螅∣O)模型提供一套優(yōu)秀的實現(xiàn)。同樣的模型能夠用來開發(fā)編程代碼和關(guān)系型數(shù)據(jù)庫結(jié)構(gòu)。 關(guān)系型數(shù)據(jù)庫技術(shù)是意義深遠(yuǎn)
1. 介紹
許多人認(rèn)為面向?qū)ο蟾拍詈完P(guān)系型數(shù)據(jù)庫相互不一致,并且不能結(jié)合。事實上完全相反!經(jīng)過靈活的使用,一個關(guān)系型數(shù)據(jù)庫能夠為面向?qū)ο螅∣O)模型提供一套優(yōu)秀的實現(xiàn)。同樣的模型能夠用來開發(fā)編程代碼和關(guān)系型數(shù)據(jù)庫結(jié)構(gòu)。
關(guān)系型數(shù)據(jù)庫技術(shù)是意義深遠(yuǎn)的、強大的,但它比許多開發(fā)商使你相信的要難得多。單個表是簡單易懂的、直觀的。但由數(shù)以百計的表組成(這是常見的)的應(yīng)用要徹底了解是相當(dāng)困難的。這正是OO模型有用之處。 OO模型使你深入地、連貫地思考問題。
OO模型提供一種問題的超結(jié)構(gòu)(superstructure)的思考方式,然后該方式能夠用關(guān)系型數(shù)據(jù)庫的更低層的組成塊來實現(xiàn)。
本文章綜合地討論了關(guān)系型數(shù)據(jù)庫技術(shù),而不是集中于特定的產(chǎn)品上。我們將不討論物理設(shè)計細(xì)節(jié)(例如存儲分配和物理聚集),因為它們是依賴于產(chǎn)品的。
用關(guān)系型數(shù)據(jù)庫實現(xiàn)UML模型有兩個方面:映射結(jié)構(gòu)(第2節(jié))和映射功能(第3節(jié))。第4節(jié)注解了面向?qū)ο蟮疥P(guān)系型數(shù)據(jù)庫的擴展。第5節(jié)總結(jié)本文章。
2. 結(jié)構(gòu)映射到表
UML對象模型在本質(zhì)上只是一個擴展的實體-關(guān)系(ER)模型 。使用設(shè)計數(shù)據(jù)庫的ER模型的方式受到普遍接受,而我們以一種近似的但更強大的方式-使用UML對象模型。OO模型的主要優(yōu)勢在于編程和數(shù)據(jù)庫的相同的模 型工作。而且,作為考慮功能性的一種方式(第3節(jié)),我們強調(diào)OO模型的導(dǎo)航。這一節(jié)顯示如何實現(xiàn)UML對象模型的主要構(gòu)造。
2.1 標(biāo)識(identity)
實現(xiàn)對象模型的第一步是處理標(biāo)識。我們從定義幾個術(shù)語開始。
1)候選鍵(candidate key)是一個或多個屬性的組合,它唯一地確定某個表里的記錄。一個候選鍵里的屬性集必須是最小化的;除非破壞唯一性,否則屬性不能從候選鍵刪除。候選鍵里的屬性不能為空。
2)主鍵(primary key)是一個特定地選定的候選鍵,用來優(yōu)先地參考記錄。
3)外鍵(foreign key)是一個候選鍵的參考。外鍵必須包括每個要素屬性的一個值,或者它必須全部為空。外鍵用來實現(xiàn)關(guān)聯(lián)和一般化。
正常地你應(yīng)該為每個表定義一個主鍵,盡管偶爾有例外。我們強烈建議所有的外鍵都只指向主鍵而不是其它的候選鍵。
定義主鍵有兩種基本的方法:
1)基于存在的標(biāo)識。你應(yīng)該為每個類表加一個對象標(biāo)識符屬性,并將它設(shè)為主鍵。每個關(guān)聯(lián)表的主鍵包括一個或更多的相關(guān)類的標(biāo)識符。基 于存在的標(biāo)識符有作為單獨屬性的優(yōu)勢,占位小且大小相同。只要你的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS)受支持,基于存在的標(biāo)識符就沒有性能的劣勢。(多數(shù) RDBMS提供有效的基于存在的標(biāo)識符的分配順序號碼。)唯一的劣勢是基于存在的標(biāo)識符在維護時內(nèi)沒有固有的意義。
2)基于值的標(biāo)識。一些真實世界的屬性的組合確定了每個對象。基于值的標(biāo)識有不同的優(yōu)勢。主鍵對于用戶有固有的意義,容易進行調(diào)試和數(shù)據(jù)庫維護。在另一面,基于值的主鍵很難改變。一個主鍵的改變需要傳播到許多外鍵。一些對象沒有自然的真實世界里的標(biāo)識符。
我們推薦你在超過30個類的RDBMS應(yīng)用里使用基于存在的標(biāo)識。基于存在和基于值的標(biāo)識都是所有RDBMS應(yīng)用的可行選項。
2.2 域(屬性類型)
屬性類型是UML術(shù)語,對應(yīng)于數(shù)據(jù)庫著作里的域的術(shù)語。比起直接用數(shù)據(jù)類型,域提升到更一致的設(shè)計,并便利了應(yīng)用的定位。
簡單域很容易實現(xiàn)。你僅僅要定義相應(yīng)的數(shù)據(jù)類型和大小。并且每個用了域的屬性,你都必須為每個域約束加入一條SQL查詢子句。簡單域的一些例子是:名字(name),長字符(longString)和電話號碼(phone-Number)。
一個枚舉域把一個屬性限制在一系列的值里。枚舉域比簡單域?qū)崿F(xiàn)起來更復(fù)雜,圖表1顯示了四個方法。
圖表1:枚舉的實現(xiàn)方法
2.3類
正常情況下,我們把每個類映射為一個表,每個屬性映射為一個列。你可能因一個已產(chǎn)生的標(biāo)識符(基于存在的標(biāo)識符)、隱藏的關(guān)聯(lián)(第2.4節(jié))和通用鑒別器(第2.5節(jié))需要一些另外的列。
2.4關(guān)聯(lián)
現(xiàn)在我們討論關(guān)聯(lián)的實現(xiàn)。我們已經(jīng)把我們的陳述分為建議的映射(我們正常使用的映射),可選的映射(我們偶爾使用的映射)和不鼓勵的映射(我們遇到的應(yīng)該避免的錯誤)。我們所有的例子都采用基于存在的標(biāo)識。
2.4.1 建議的映射
多對多關(guān)聯(lián)。用一個特別的表(圖表2)來實現(xiàn)一個多對多關(guān)聯(lián)。關(guān)聯(lián)的主鍵是每個類的主鍵的合并。那些省略號(...)表示在模型里沒有顯示出來的屬性。主鍵用黑體字體顯示。
一對多關(guān)聯(lián)。把一個外鍵隱藏在“多”表(圖表3)。角色名字成為外鍵屬性名字的一部分。
零或一對一關(guān)聯(lián)。把外鍵隱藏在“零或一”表(圖表4)。
其它一對一關(guān)聯(lián)。把外鍵隱藏在任一表里。
圖表2:建議的實現(xiàn):特殊的多對多關(guān)聯(lián)表
圖表3:建議的實現(xiàn):隱藏的一對多關(guān)聯(lián)
圖表4:建議的實現(xiàn):隱藏的零或一對一關(guān)聯(lián)
可選的映射 正常情況下我們使用建議的映射。但有些偶爾的情況,可選的映射更合適。
特別的表。你也可以用特別的表(圖表5)來實現(xiàn)一對多和一對一關(guān)聯(lián)。特別的表給了你更統(tǒng)一的設(shè)計和更大的擴展性。無論如何,特別的關(guān)聯(lián)表打碎了數(shù)據(jù)庫,并增加了表的數(shù)量。此外,特別的關(guān)聯(lián)表不能強迫一個更低的多重性限度為“一”。
圖表5:可選的實現(xiàn):特別的一對x關(guān)聯(lián)表
不鼓勵的映射 我們已經(jīng)注意到有些開發(fā)者選擇有缺陷的映射。我們要注意這些映射以便可以避免。 合并。不要合并多個類,不要把關(guān)聯(lián)強制成為一個單獨的表(圖表6)。這樣減少了表的數(shù)量,但會干擾第三范式。
兩次隱藏一對一關(guān)聯(lián)。不要把一個一對一關(guān)聯(lián)隱藏兩次,每次隱藏在一個類里(圖表7)。這是多余的,無助于性能。
相同的屬性。不要用相同的屬性來實現(xiàn)多個關(guān)聯(lián)角色(圖表8)。相同的屬性使編程復(fù)雜,降低了擴展性。 泛化 現(xiàn)在我們討論泛化。我們這里只論述單個繼承。 建議的映射 最簡單的方法是只映射超類和每個子類為一個表。所有的表共享一個共同的主鍵。應(yīng)用必須執(zhí)行子類的劃分,因為RDBMS支持。(關(guān)于后者的詳盡的描述,請參 閱第4節(jié)。)
特別的表。映射超類和每個子類為一個表(圖表9)。所有的表共享一個共同的主鍵。鑒別器指出每個子類記錄的適當(dāng)?shù)某惐怼?
圖表9:建議的實現(xiàn):分開的超類和子類表
可選的映射 泛化有幾個可選的映射。 消除。你可以優(yōu)化除去那些除了主鍵外沒有別的屬性的類(圖表10)。這樣減少了表的數(shù)量,但提供更少的正規(guī)實現(xiàn)。
減少超類屬性。你可以除去超類表并把超類屬性復(fù)制到每個子類(圖表11)。這樣可以有描述每個對象為一個表的優(yōu)勢。無論如何,它將引起數(shù)據(jù)庫結(jié)構(gòu)的冗余,你查找一個對象時可能需要搜索多個子類表。
增加子類屬性。作為第三個可選項,你可以除去子類表并存儲所有的子類屬性到超類表里(圖表12)。這樣用一個表描述每個對象,但干擾了第二范式。
圖表10:可選的實現(xiàn):消除不必的子類表
圖表11:可選的實現(xiàn):減少超類屬性
圖表12:可選的實現(xiàn):增加子類屬性
參考完整性 一旦你已經(jīng)建立了表,你就應(yīng)該定義參考完整性動作來明確對象模型的意義。(不要使用SQL觸發(fā)器來實現(xiàn)參考完整性!)如果你使用基于存在的標(biāo)識,你將不需 要傳播更新的結(jié)果。我們建議以下對刪除的參考完整性方針: 泛化。級聯(lián)從泛化實現(xiàn)中產(chǎn)生的外鍵的刪除。
隱藏的關(guān)聯(lián),最小化多樣性為零。正常地把外鍵設(shè)為空,但有時候你可能要禁止刪除。
隱藏的關(guān)聯(lián),最小化多樣性為空。你可以級聯(lián)一個刪除的結(jié)果或者禁止該刪除。
關(guān)聯(lián)表。正常地我們級聯(lián)關(guān)聯(lián)表里對記錄的刪除。可是,有時候我們禁止一個刪除。
我們已經(jīng)簡要地論及參考完整性,因為它是個高級話題。參考有更多的解釋z和例子。 索引 實現(xiàn)數(shù)據(jù)庫結(jié)構(gòu)的最后的一步是加入索引來調(diào)整數(shù)據(jù)庫性能。正常地,你應(yīng)該為每個主鍵和候選鍵定義一個唯一的索引。(多數(shù)RDBMS作為SQL主鍵和候選鍵 約束的副作用來建立唯一的索引。)你也應(yīng)該為每個被主鍵或候選鍵所約束的外鍵建立一個索引。
我們強調(diào)索引的重要性。外鍵和主鍵的索引使在對象模型里能快速地遍歷是不容懷疑的。你必須包括這些索引否則你將使用戶感到灰心。你應(yīng)該在你的數(shù)據(jù)庫開始設(shè)計階段里加入索引,因為它們很容易加入并且也沒有什么好理由推遲加入。
數(shù)據(jù)庫管理員(DBA)可能為經(jīng)常請求的查詢定義了額外的索引。DBA也可能采用產(chǎn)品相關(guān)的調(diào)整性能的機制。 范式 范式是關(guān)系型數(shù)據(jù)庫設(shè)計的提高數(shù)據(jù)一致性的有效方法。我們的書3討論了范式,但我們關(guān)于這個問題卻言過甚微。我們將利用這篇文章的機會來澄清我們的觀點。 如果你不熟悉范式你可以跳過這節(jié)。我們的說明是針對關(guān)系型設(shè)計人員,他們正在嘗試用面向?qū)ο筮m應(yīng)他們原有的技能。
范式是正確設(shè)計關(guān)系型數(shù)據(jù)庫的精確的原則。同樣地,它們與使用了什么開發(fā)技術(shù)是無關(guān)的 - 基于屬性的設(shè)計、基于實體的設(shè)計、面向?qū)ο笤O(shè)計或其它什么。 過去使用基于屬性設(shè)計的方法,開發(fā)人員不得不非常注意范式;范式提供了分組數(shù)據(jù)的根據(jù)。相反地,范式對于基于面向?qū)ο螅ɑ蚧趯嶓w)的開發(fā)不是很重要。如 果你采用OO方法并且你的模型經(jīng)過很好的構(gòu)思,那你就正在把數(shù)據(jù)組織成為有意義的單位,也在本質(zhì)上滿足了范式的規(guī)定。如果你愿意,你仍能夠檢查范式,但這 樣的檢查是不必要的。 摘要 圖表13總結(jié)了我們已經(jīng)陳述的映射規(guī)則。這些映射規(guī)則的完整例子,包括一個UML對象模型,能夠在這篇完整的擴展版本里找到(Adobe Acrobat PDF文件)。
圖表13:推薦的映射規(guī)則的摘要
把功能映射到SQL命令 對象模型為數(shù)據(jù)庫應(yīng)用提供三種主要的用途。 結(jié)構(gòu)。對象模型指明數(shù)據(jù)庫結(jié)構(gòu)。我們已經(jīng)在第二節(jié)探討了這個方面。
約束。對象模型也指明了能存儲的數(shù)據(jù)上的重要的約束。相匹配的實現(xiàn)必須為迎合這些約束而努力。我們的映射規(guī)則的處理方法以及第二節(jié)里的參考完整性指出了許多約束。(本文沒有論及的另外的UML構(gòu)造,能獲取更多的約束。)
潛在估算。一個對象模型指明潛在估算;它是關(guān)于引起哪些查詢和如何公式化的藍(lán)圖。第三節(jié)將簡要地闡明第三個目的。
對象模型不僅僅是被動的數(shù)據(jù)結(jié)構(gòu),相反它們能夠幫助你思考一個應(yīng)用的功能。你可以根據(jù)遍歷一個對象模型說出它的許多功能。例如,根據(jù) 我們對一個模型檢查用例時的遍歷,我們進行思索。這強調(diào)對象模型的估算能力對于RDBMS應(yīng)用是特別重要的,因為遍歷表達(dá)式可以直接映射到SQL代碼。
UML對象約束語言(Object Constraint Language,OCL)有助于表達(dá)遍歷。點符號導(dǎo)航從對象到對象和對象到屬性。方括號表示對象集合的過濾器。我們加入冒號(:)操作符來表示泛化的遍 歷;因為我們正常地用多個表來實現(xiàn)一個泛化繼承,清楚的遍歷很有用。
圖表14里的遍歷表達(dá)式例子是基于我們創(chuàng)建的UML對象模型上的(請參閱本文的擴展版本(Adobe Acrobat PDF文件)),我們把它們映射為SQL代碼。我們用冒號開始SQL編程變量。
圖表14:對象模型遍歷和SQL代碼的例子
到RDBMS的OO擴展 數(shù)據(jù)庫團體對RDBMS的OO擴展有興趣。產(chǎn)品和SQL標(biāo)準(zhǔn)正嘗試加入到OO擴展里。我們將簡要地陳述一下這個技術(shù)的方向。 抽象數(shù)據(jù)類型(ADT)。這是個好主意,擴展RDBMS的能力。開發(fā)商為這個技術(shù)使用了許多名字,例如Oracle cartridge和Informix data blades。ADT的缺點是它們把你緊緊綁在特定的一個開發(fā)商上;ADT的范疇超越了SQL標(biāo)準(zhǔn)。因此,你應(yīng)該只在ADT的好處很明顯的時候才使用。
在關(guān)于ADT如何適合數(shù)據(jù)庫開發(fā)的著作里有一些混亂。如果你使用OMT開發(fā)過程,你能夠用屬性實現(xiàn)簡單域,用ADT實現(xiàn)復(fù)雜域。你仍 應(yīng)該用表實現(xiàn)類。 SQL3指針。最新的SQL標(biāo)準(zhǔn)的版本,SQL3,加入了作為一種數(shù)據(jù)類型的指針符號。顯然,其意圖是支持導(dǎo)航和面向?qū)ο蟆N覀儗τ赟QL3指針最友善的 評語是,它們是嫁接的,是可以忽略的。更深入的批評是,指針在理論上是荒謬的,增加了復(fù)雜性,又沒有擴展SQL的表達(dá)能力。CJ Date在上次的九月對象/關(guān)系型會議上雄辯地討論了這一點。
好了,那么我們冷淡地對待抽象數(shù)據(jù)類型和SQL指針的指責(zé)。但我們相當(dāng)喜歡面向?qū)ο蠹夹g(shù)和關(guān)系型數(shù)據(jù)庫。有兩個為RDBMS的擴展可 以使它們更容易用于OO技術(shù)。我們將很樂意看到RDBMS開發(fā)商把這些能力加入到他們的產(chǎn)品中。 擴展的參考完整性動作來支持泛化。當(dāng)前的參考完整性機制是單向的。為了完全支持泛化,我們需要一個雙向的機制。這樣,一條超類記錄就可以依賴一條子類記 錄。并且,一條子類記錄就可以依賴一條超類記錄。我們通過例子可以最好地解釋這點。
圖表15摘錄于我們的在3的財務(wù)案例學(xué)習(xí)。我們用資產(chǎn)超類來統(tǒng)一某些沒有顯示在摘錄里的通用的數(shù)據(jù)和功能。一項資產(chǎn)可以是一只股票或股票特權(quán)。一只股票可以有許多它的股票特權(quán)。例如,IBM股票可以有許多達(dá)到價格和過期日期的寫下的放或叫特權(quán)。
圖表15:參考完整性和泛化的例子
我們推薦的泛化實現(xiàn)是特別的表 - 映射該超類和每個子類為一個表。然后,我們就可以使用參考完整性使股票特權(quán)和股票的記錄依賴于資產(chǎn)。一個資產(chǎn)記錄的刪除級聯(lián)到相應(yīng)的子類記錄、股票特權(quán)或 股票的刪除上。我們也能夠定義一個參考完整性動作,這樣一個股票的刪除就級聯(lián)到關(guān)聯(lián)的股票特權(quán)記錄的刪除。
現(xiàn)在問題如下。如果我們刪除的一項資產(chǎn)是一只股票,資產(chǎn)記錄的刪除級聯(lián)到引起股票記錄的刪除。隨后,股票記錄的刪除級聯(lián)引起所有股票 特權(quán)記錄的刪除。但現(xiàn)在參考完整性使我們失敗了:一個股票特權(quán)記錄的刪除并不引起一項資產(chǎn)記錄的刪除。刪除級聯(lián)只能從超類走到子類。為了完全的行為,級聯(lián) 應(yīng)該雙向地走下去。
當(dāng)前有用的參考完整性的工作是做更多的編程(也即做更多的工作和風(fēng)險更多故障)。在我們的用例學(xué)習(xí)的實現(xiàn)里,用戶隨時要刪除一項是股 票的資產(chǎn),我們不得不書寫額外的代碼來首先檢查關(guān)聯(lián)股票特權(quán)的存在性,然后刪除它們。 支持交叉表的記錄劃分。單獨繼承(泛化的最常見方式)的含義是一個超類的每個實例都是用多數(shù)只有一個子類來例示。現(xiàn)在的RDBMS不能容易地加強這個約 束。例如,沒有什么防止下面的情形。一只股票可以用ID18加入到資產(chǎn)表,用ID18加入到股票表,并且也可以用ID18加入到股票特權(quán)表。再一次地,我 們?yōu)榱舜_信行為的完整,不得不作額外的編程,而不是寫一個簡單的聲明的約束
結(jié)論
本文陳述了用關(guān)系型數(shù)據(jù)庫實現(xiàn)UML模型的快速的概觀。我們希望本文向你演示的技術(shù)是足夠適宜的。一個訓(xùn)練有素的開發(fā)人員能夠用關(guān)系 型數(shù)據(jù)庫準(zhǔn)備一套優(yōu)秀的OO模型的實現(xiàn)。如果你要關(guān)于實現(xiàn)機制的更多的細(xì)節(jié),參考3有另外的信息,并且也覆蓋了我們沒有在這里討論的一些高級模型建模結(jié) 構(gòu)。
來源 http://tech.ccidnet.com/art/291/20030811/58724_1.html
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com