海鷗航際

          JAVA站
          posts - 11, comments - 53, trackbacks - 1, articles - 102
          對象/關(guān)系映射--聚合模式

          摘要
          在面向?qū)ο蠼F陂g(OOA)最難回答的問題是,何時使用聚合,何時使用關(guān)聯(lián)。性能和靈活性的權(quán)衡將會影響到這個問題的答案。你可以使用Single Table Aggregation。這是一種最自然的聚合映射方式。你也可以使用Foreign Key Aggregation,它常常用于處理1:n聚合的映射,我們將在Foreign Key Aggregation的相關(guān)章節(jié)中討論它。(2002-08-20 12:28:18)

          By axing

          聚合映射的模式

          在面向?qū)ο蠼F陂g(OOA)最難回答的問題是,何時使用聚合,何時使用關(guān)聯(lián)。性能和靈活性的權(quán)衡將會影響到這個問題的答案。你可以使用Single Table Aggregation。這是一種最自然的聚合映射方式。你也可以使用Foreign Key Aggregation,它常常用于處理1:n聚合的映射,我們將在Foreign Key Aggregation的相關(guān)章節(jié)中討論它。

          模式:Single Table Aggregation

          摘要:

          該模式展示了如何通過把所有的聚合的對象屬性集成到單個的表中的方法把聚合映射到一個關(guān)系數(shù)據(jù)模型。

          示例:

          考慮下列的對象模型:

          一個AddressType

          圖1.一個AddressType,為其它的對象所聚合。

          問題:

          如何將聚合映射到關(guān)系表中?

          約束:

          1. 性能:為了得到最佳的性能,該方案應(yīng)該在一次的數(shù)據(jù)庫訪問中,不用Join操作獲取一個對象。數(shù)據(jù)庫訪問應(yīng)該只獲取最少的頁面,以節(jié)省IO帶寬。
          2. 可維護性:為了獲得最佳的可維護性,那些為多個對象所聚合的聚合類型,應(yīng)該映射到一組表中,而不是分散到物理數(shù)據(jù)模型的各個點上。在數(shù)據(jù)模型層次上實行標(biāo)準化,這樣可以使維護簡單。
          3. 數(shù)據(jù)庫的一致性:聚合意味著被聚合對象的生命周期和需要聚合的對象的生命周期是相互耦合的。這一點需要由數(shù)據(jù)庫或應(yīng)用程序代碼來保證。

          解決方案:

          把被聚合對象的屬性和使用聚合對象的屬性放在同一張表中。

          結(jié)構(gòu):

          使用聚合的對象被轉(zhuǎn)換為物理數(shù)據(jù)模型的一張表中,被聚合對象的數(shù)據(jù)集成到該表中。

          解決方法示例:

          我們?yōu)镃ustomer對象創(chuàng)建Customer表。InvoiceAddress和DeliveryAddress都集成到Customer表中。

          將一個被聚合的對象類型映射到使用聚合的對象的數(shù)據(jù)庫表中

          圖2.將一個被聚合的對象類型映射到使用聚合的對象的數(shù)據(jù)庫表中。

          我們使用前綴來區(qū)分同類的屬性。這有點類似于C++中的命名空間的概念,例如Customer.DeliveryAddress.Street。

          結(jié)論:

          1. 性能:在性能方面,該方案是最佳的,因為只需要訪問一張表就能夠獲取一個帶聚合的對象,并讀入所有聚合對象。另一方面,由于聚合對象的字段的增多,一次讀取將會增大數(shù)據(jù)庫讀入的頁面數(shù),導(dǎo)致IO帶寬的浪費。
          2. 可維護性和靈活性:如果聚合的對象類型被多個對象所引用,那么將會降低可維護性,因為每一次對聚合對象類型的修改都會導(dǎo)致對所有引用聚合對象的修改。
          3. 數(shù)據(jù)庫的一致性:刪除使用聚合的對象時,聚合對象將會自動刪除。不需要任何其它的程序或數(shù)據(jù)庫觸發(fā)器來控制。
          4. 特殊查詢:類似查詢數(shù)據(jù)庫中所有的AddressType對象之類的查詢,都會變得很難處理。

          實現(xiàn):

          1. 命名規(guī)則:需要為聚合的對象的屬性考慮前綴或其它的命名規(guī)則。在上面的例子中,我們使用屬性名稱的縮寫形式作為前綴。
          2. 物理數(shù)據(jù)庫的頁面大小:將聚合對象和使用聚合對象放在同一張表中,在一定程度上彌補了由于對象的部分屬性存儲在另一個數(shù)據(jù)庫頁面上的性能損失。這種情況下,讀入的是兩個頁面,而不是一個。

          變化:

          我們已經(jīng)討論了使用聚合對象類型和聚合對象類型之間最簡單的1:1關(guān)系。Foreign Key Association模式描述了兩種對象類型間1:n的關(guān)系,Overflow Table則展示了在1:n的關(guān)系下避免采用外鍵的技巧。

          相關(guān)模式:

          Foreign Key Aggregation模式是Single Table Aggregation模式的備選方案。參考Representing Collections in a Relational Database [Bro+96]。當(dāng)應(yīng)用到普通的關(guān)系型數(shù)據(jù)庫訪問層的時候,還可以對比Denormalization [Kel+97]。

          參考:

          《Mainstream Objects》(Ed Yourdon [You+95] )在第21章完整的討論了在建模時期何時使用聚合和關(guān)聯(lián)、以及如何使用它們的問題。

           

          聚合映射的模式

          在面向?qū)ο蠼F陂g(OOA)最難回答的問題是,何時使用聚合,何時使用關(guān)聯(lián)。性能和靈活性的權(quán)衡將會影響到這個問題的答案。你可以使用Single Table Aggregation。這是一種最自然的聚合映射方式。你也可以使用Foreign Key Aggregation,它常常用于處理1:n聚合的映射,我們將在Foreign Key Aggregation的相關(guān)章節(jié)中討論它。

          模式:Single Table Aggregation

          摘要:

          該模式展示了如何通過把所有的聚合的對象屬性集成到單個的表中的方法把聚合映射到一個關(guān)系數(shù)據(jù)模型。

          示例:

          考慮下列的對象模型:

          一個AddressType

          圖1.一個AddressType,為其它的對象所聚合。

          問題:

          如何將聚合映射到關(guān)系表中?

          約束:

          1. 性能:為了得到最佳的性能,該方案應(yīng)該在一次的數(shù)據(jù)庫訪問中,不用Join操作獲取一個對象。數(shù)據(jù)庫訪問應(yīng)該只獲取最少的頁面,以節(jié)省IO帶寬。
          2. 可維護性:為了獲得最佳的可維護性,那些為多個對象所聚合的聚合類型,應(yīng)該映射到一組表中,而不是分散到物理數(shù)據(jù)模型的各個點上。在數(shù)據(jù)模型層次上實行標(biāo)準化,這樣可以使維護簡單。
          3. 數(shù)據(jù)庫的一致性:聚合意味著被聚合對象的生命周期和需要聚合的對象的生命周期是相互耦合的。這一點需要由數(shù)據(jù)庫或應(yīng)用程序代碼來保證。

          解決方案:

          把被聚合對象的屬性和使用聚合對象的屬性放在同一張表中。

          結(jié)構(gòu):

          使用聚合的對象被轉(zhuǎn)換為物理數(shù)據(jù)模型的一張表中,被聚合對象的數(shù)據(jù)集成到該表中。

          解決方法示例:

          我們?yōu)镃ustomer對象創(chuàng)建Customer表。InvoiceAddress和DeliveryAddress都集成到Customer表中。

          將一個被聚合的對象類型映射到使用聚合的對象的數(shù)據(jù)庫表中

          圖2.將一個被聚合的對象類型映射到使用聚合的對象的數(shù)據(jù)庫表中。

          我們使用前綴來區(qū)分同類的屬性。這有點類似于C++中的命名空間的概念,例如Customer.DeliveryAddress.Street。

          結(jié)論:

          1. 性能:在性能方面,該方案是最佳的,因為只需要訪問一張表就能夠獲取一個帶聚合的對象,并讀入所有聚合對象。另一方面,由于聚合對象的字段的增多,一次讀取將會增大數(shù)據(jù)庫讀入的頁面數(shù),導(dǎo)致IO帶寬的浪費。
          2. 可維護性和靈活性:如果聚合的對象類型被多個對象所引用,那么將會降低可維護性,因為每一次對聚合對象類型的修改都會導(dǎo)致對所有引用聚合對象的修改。
          3. 數(shù)據(jù)庫的一致性:刪除使用聚合的對象時,聚合對象將會自動刪除。不需要任何其它的程序或數(shù)據(jù)庫觸發(fā)器來控制。
          4. 特殊查詢:類似查詢數(shù)據(jù)庫中所有的AddressType對象之類的查詢,都會變得很難處理。

          實現(xiàn):

          1. 命名規(guī)則:需要為聚合的對象的屬性考慮前綴或其它的命名規(guī)則。在上面的例子中,我們使用屬性名稱的縮寫形式作為前綴。
          2. 物理數(shù)據(jù)庫的頁面大小:將聚合對象和使用聚合對象放在同一張表中,在一定程度上彌補了由于對象的部分屬性存儲在另一個數(shù)據(jù)庫頁面上的性能損失。這種情況下,讀入的是兩個頁面,而不是一個。

          變化:

          我們已經(jīng)討論了使用聚合對象類型和聚合對象類型之間最簡單的1:1關(guān)系。Foreign Key Association模式描述了兩種對象類型間1:n的關(guān)系,Overflow Table則展示了在1:n的關(guān)系下避免采用外鍵的技巧。

          相關(guān)模式:

          Foreign Key Aggregation模式是Single Table Aggregation模式的備選方案。參考Representing Collections in a Relational Database [Bro+96]。當(dāng)應(yīng)用到普通的關(guān)系型數(shù)據(jù)庫訪問層的時候,還可以對比Denormalization [Kel+97]。

          參考:

          《Mainstream Objects》(Ed Yourdon [You+95] )在第21章完整的討論了在建模時期何時使用聚合和關(guān)聯(lián)、以及如何使用它們的問題。

          模式:Foreign Key Aggregation

          摘要:

          該模式顯示了如何使用外鍵將聚合映射到一個關(guān)系數(shù)據(jù)模型中。

          環(huán)境:

          重新考慮Single Table Aggregation模式中的例子(見圖1)。假設(shè)你需要把AddressType視為單個的對象,并希望獲得比Single Table Aggregation更好的可維護性。

          問題:

          如何將聚合映射到關(guān)系表?

          約束:

          見Single Table Aggregation模式。

          解決方案

          為聚合類型使用單獨的表。在表中插入Synthetic Object Identity,并使用使用聚合對象表中的對象標(biāo)記做一個外鍵,連接到聚合對象。

          結(jié)構(gòu):

          AggregatingObject(使用聚合對象)映射到一張表,而AggregatedObject(聚合對象)映射到另一張表。聚合對象的表中包含了Synthetic Object Identity。SyntheticOID字段被使用聚合表中的AggregatedObjectsOID外鍵字段引用。

          解決方案示例

          我們使用Single Table Aggregation模式中的例子。Customer表中包含了兩個外鍵引用,指向AddressType表。AddressType表包含了Synthetic Object Identity字段,用于連接兩張表。

          現(xiàn)在從數(shù)據(jù)庫中獲取一個客戶對象需要三次訪問數(shù)據(jù)庫(一次是對Customer表,另兩次是對AddressType:InvoiceAddress和DeliveryAddress),這要比Single Table Aggregation中多兩次。

          如果AddressType表中增加指回Customer表中Synthetic Object Identity字段的回指字段的話,你就可以用連接來減少訪問次數(shù)。這樣做的代價是在取客戶屬性時同時取回兩個地址。

          結(jié)論:

          1. 性能:Foreign Key Aggregation需要連接操作或至少兩次的數(shù)據(jù)庫訪問,而Single Table Aggregation只需要一次的數(shù)據(jù)庫操作。如果訪問聚合對象的概率較小,這個性能還是可以接受的,如果聚合對象總是需要和使用聚合對象一同返回,那么就需要慎重的思考性能問題了。
          2. 可維護性:將對象做分解,例如單獨存放AddressType,這將使得維護更加容易,并提高映射的靈活性。
          3. 數(shù)據(jù)庫的一致性:聚合對象不會隨著使用聚合對象的刪除而自動刪除。為做到這一點,需要編程或使用數(shù)據(jù)庫觸發(fā)器來實現(xiàn)。
          4. 特殊查詢:將聚合對象放到單獨的表中可以簡化對這些對象的查詢。

          實現(xiàn)

          1. 可以考慮使用領(lǐng)域邏輯中的關(guān)鍵字來代替Synthetic Object Identitie。使用領(lǐng)域關(guān)鍵字的缺點是它們無法指回owner對象。
          2. 考慮在聚合對象中插入一個指回使用聚合對象的連接。在地址這個例子中,就是在地址表中插入一個字段,來表明AddressType對象的所有者。這個所有者可能是一個員工、一個客戶,或是其它需要使用AddressType的對象。雙向的關(guān)聯(lián)在查詢、一致性檢查和其它方面提供了方便。為了得到聚合對象的所有者,你不需要再次搜索使用聚合對象的表。另一方面,返回連接的開銷比較昂貴。

          相關(guān)模式

          其備選方案為Single Table Aggregation。Foreign Key Association模式的工作方式和該模式非常接近。見Representing Collections in a Relational Database [Bro+96]。

          主站蜘蛛池模板: 日土县| 邓州市| 永平县| 静安区| 隆安县| 房山区| 若羌县| 奈曼旗| 拜泉县| 金山区| 嘉定区| 曲麻莱县| 三穗县| 昆明市| 乐安县| 建宁县| 苏尼特左旗| 通山县| 永济市| 横山县| 上栗县| 肇州县| 荆州市| 镇沅| 扬州市| 宾阳县| 陵水| 辰溪县| 淳安县| 汤阴县| 岗巴县| 枣强县| 临颍县| 湖北省| 龙江县| 石景山区| 孟连| 宾阳县| 安远县| 平乐县| 遂川县|