天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

理解O/R Mapping

  本文的目的是以最精煉的語言,理解什么是O/R Mapping,為什么要O/R Mapping,和如何進行O/R Mapping。

  什么是O/R Mapping?

  廣義上,ORM指的是面向?qū)ο蟮膶ο竽P秃完P系型數(shù)據(jù)庫的數(shù)據(jù)結構之間的相互轉(zhuǎn)換。

  狹義上,ORM可以被認為是,基于關系型數(shù)據(jù)庫的數(shù)據(jù)存儲,實現(xiàn)一個虛擬的面向?qū)ο蟮臄?shù)據(jù)訪問接口。理想情況下,基于這樣一個面向?qū)ο蟮慕涌冢志没粋€OO對象應該不需要要了解任何關系型數(shù)據(jù)庫存儲數(shù)據(jù)的實現(xiàn)細節(jié)。

  為什么需要O/R Mapping?

  廣義上,因為我們需要面向?qū)ο髞砻枋鑫覀兊臉I(yè)務,我們也需要關系型數(shù)據(jù)庫來存儲我們的數(shù)據(jù)。

  有人可能會提到,我們未必要用面向?qū)ο髞砻枋鰳I(yè)務,或者未必用關系型數(shù)據(jù)庫來存儲數(shù)據(jù)。沒錯,但是,至少,還是有相當大部分的程序,同時需要這兩者的合作。存在即合理。因為同時需要彼此,兩者都客觀存在,就值得討論。

  既然從廣義上,存在即合理,無需討論為什么需要ORM,很多關于ORM的討論,其實都是針對上面提到的狹義的定義。但是即使到目前為止,真正能夠完美的實現(xiàn)這個狹義定義的ORM的工具,其實還并不存在(很多工具如Hibernate,已經(jīng)相當接近,但是,離完美還有相當距離)。

  既然還不存在,那么,在討論需不需要之前,我們恐怕要先討論一下,是否可能,即從理論上,從數(shù)學上,面向?qū)ο蟮膶ο竽P秃完P系型數(shù)據(jù)庫的數(shù)據(jù)結構之間,到底能不能做到完美的映射?要回答這個問題,我們要解決兩個難題。

  O/R阻抗失衡

  第一個難題,叫“O/R阻抗失衡(O/R Impedance Mismatch)”,指的是OO對象模型和關系型數(shù)據(jù)庫的數(shù)據(jù)結構之間的,設計理念上的差異。OO的設計理念,是以最正確的語義來描述真實世界;而關系型數(shù)據(jù)庫的設計理念,則是從數(shù)學的角度,如何更有效的存儲和管理數(shù)據(jù)。由于兩者設計理念的差異,導致它們盡管從數(shù)據(jù)結構上,可能很相近,但是關注點往往是不同的。

  例如:

  • 從OO的角度,凡是語義明確,每一個對象語義上的屬性,就應該定義為一個屬性;從關系型數(shù)據(jù)庫的角度,有可能考慮到一些屬性從來不會被作為查詢條件,而把多個語義上的屬性,以一定的格式,存在一個數(shù)據(jù)表的字段中,也有可能因為一組語義上的屬性使用的頻度完全不同與另一組屬性,即使他們語義上屬于一個對象,也有可能將他們拆分成兩個數(shù)據(jù)表來存儲
  • 從OO的角度,對象只關心自己的固有屬性,不需要被唯一標識;但是,從關系型數(shù)據(jù)庫的角度,一般一個數(shù)據(jù)表中的每一行數(shù)據(jù)都需要要一個唯一標識,且很可能是語義上沒有意義的,如自增長的標識。
  • 從OO角度的優(yōu)化,一般遵循SOLID這樣的原則,以更正確的語義來組織對象;從關系型數(shù)據(jù)庫角度的優(yōu)化,往往為了查詢性能,來修改字段的類型、長度,修改索引,甚至分表、分庫。
  • ...

  一個ORM工具想要通過簡單的配置,完美的解決“O/R阻抗失衡”問題,在我看來幾乎是不可能的。但是,一定程度上,通過靈活的配置支持絕大多數(shù)常見的映射策略,再加上提供可供用戶通過自定代碼來擴展的接口的話,應該還是可以相當接近完美的。

  文化阻抗失衡

  第二個難題,叫“文化阻抗失衡(Cultural Impedance Mismatch)”,指的是關系型數(shù)據(jù)專家和面向?qū)ο髮<抑g的文化差異。關于這個難題的最經(jīng)典的爭論是“到底應該以關系型數(shù)據(jù)庫的數(shù)據(jù)結構來驅(qū)動,還是以OO的對象模型來驅(qū)動程序的開發(fā)?”。

  關于這個爭論,OO專家的主要觀點是:

  我的業(yè)務才是程序的核心,數(shù)據(jù)庫只是為我持久化數(shù)據(jù)的需求服務的,所以設計OO對象模型的時候,我不應該考慮如何存儲到關系型數(shù)據(jù)庫的問題;

  而數(shù)據(jù)庫專家的主要觀點是:
  數(shù)據(jù)才是公司的核心財富,數(shù)據(jù)的穩(wěn)定性遠遠強于OO對象模型的穩(wěn)定性,由OO對像模型來驅(qū)動數(shù)據(jù)庫架構的設計,根本保證不了性能,數(shù)據(jù)庫維護的成本根本不可接受。

  其實,爭論的真正原因即在于“關系型數(shù)據(jù)專家和面向?qū)ο髮<抑g的文化差異”。大大牛Scott W. Ambler的文章Why Data Models Shouldn't Drive Object Models(And Vice Versa),很好的解答了這個問題。

  歸根結底,既然OO和關系型數(shù)據(jù)庫都是不可缺少的部分,需要協(xié)同工作,希望做到完美的ORM,不僅僅需要好的ORM工具,更需要無論是OO專家還是數(shù)據(jù)庫專家互相了解對方的技術和設計理念。對一個OO專家,一個ORM工具,可以對其所支持的常見的映射,提供直接的支持,但是,應用這些ORM工具的OO專家,必須了解關系型數(shù)據(jù)庫,知道如何在不影響OO對象的語義的前提下,如何設計一個更容易映射到關系型數(shù)據(jù)庫的對象模型,知道如何選擇ORM工具所支持的映射方式,以及如何用自定代碼擴展ORM所不能方便支持的映射方式;同樣的,對一個關系型數(shù)據(jù)庫的專家,也需要了解OO的語義,和可能發(fā)生的重構,從而,使得所設計的數(shù)據(jù)庫結構,更容易映射到OO對象,更容易響應OO對象模型的重構。如此才是真正的和諧,真正的完美。

  小結

  綜上所述,無論對一個OO專家還是對一個關系型數(shù)據(jù)庫專家,都需要了解OO,并了解關系型數(shù)據(jù)庫,了解ORM的基本原理。離開全面的知識,一個再完美的ORM工具也無法被正確使用,擁有這些知識,則能夠充分利用已有的ORM工具來加速自己的工作,并且合理的或擴展現(xiàn)有的ORM工具,或用自定代碼,實現(xiàn)ORM工具能力之外的ORM映射。這才是理想的ORM實踐。下一章節(jié),我們就來談談一下,ORM的基本原理。

  如何進行O/R Mapping?

  簡單映射

  1. Class <-> Table

  一個Class一般可以映射為一個Table,一個Class的實例對應Table的一行數(shù)據(jù)。但是,一個Table中的每行數(shù)據(jù),一般都需要有一個主鍵來唯一標識這行數(shù)據(jù),而一個Class的每個實例,則不一定需要一個唯一標識。

  2. Property <-> Field

  一個Class的Property一般可以直接映射為Table的一個Field。但是,他們的數(shù)據(jù)類型不一定直接匹配。如果他們代表的數(shù)據(jù)類型的語義上可轉(zhuǎn)換,則Field的類型,應大于等于Property的數(shù)據(jù)類型。如果他們代表的類型語義上不可轉(zhuǎn)換,則需要在應用程序?qū)用妫M行自定義的轉(zhuǎn)換。

  繼承映射

  1. 單表映射整個繼承體系

  用一張數(shù)據(jù)庫表存儲整個繼承體系中的所有Class的數(shù)據(jù),數(shù)據(jù)表需要額外的標志字段來區(qū)分一行記錄應該映射到繼承體系中的哪一個Class,適合繼承體系層次較少,總記錄數(shù)相對較少,子類對父類的屬性擴展也相對不那么頻繁的情形。

  單表映射整個繼承體系的優(yōu)點是讀/寫繼承體系中的每個Class的數(shù)據(jù),都只需操作一張表,性能較好,并且,新增繼承類,或擴展Class屬性都只需要增減一張表的字段就可以了,易于維護;主要缺點是,因為繼承體系中所有的Class共享一張表,表中會有比較多的NULL字段值的數(shù)據(jù),浪費了一些存儲空間,同時,如果記錄數(shù)過多,表就會更龐大,也會影響表的讀寫性能。

  2. 一個Class映射一個具體表

  所謂一個Class映射一個具體表就是每個Class對應一張數(shù)據(jù)表,并且,每個數(shù)據(jù)表冗余包含其父類的所有屬性字段,并且,子類和父類共享相同的主鍵值。一個Class一個具體表方案適合需要較高查詢性能,繼承體系層次不太復雜,并且基類包含較少的屬性而子類擴展較多屬性,并且能夠承受一定的數(shù)據(jù)庫冗余的情況。

  一個Class映射一個具體表方案的優(yōu)點主要就是查詢性能好,讀操作只需操作一張表,和實體數(shù)據(jù)的對應結構清晰,數(shù)據(jù)庫表遷移和維護會比較方便;主要的缺點是數(shù)據(jù)冗余較大,因為每次插入一條子類數(shù)據(jù)時,同時要插入一份子類包含的父類字段的數(shù)據(jù)到所有父類層次表中。

  3. 一個Class映射一個擴展表

  所謂一個Class映射一個擴展表是指繼承體系中的每個Class對應一張數(shù)據(jù)表,但是,每個子類不冗余包含父類的所有屬性,而只是包含擴展的屬性和共享的主鍵值。一個Class映射一個擴展表方案適合繼承體系非常復雜,結構易變,并希望最大程度減少數(shù)據(jù)冗余的情形。

  一個Class映射一個擴展表方案的優(yōu)點是結構靈活,新增子類或插入中間的繼承類都很方便,冗余數(shù)據(jù)最少;但是缺點是,無論讀還是寫操作都會涉及到子類和所有的父類。讀操作時,必須自然鏈接查詢所有的父類對應的數(shù)據(jù)表,而插入或更新數(shù)據(jù)時,也需要寫所有的父類表。

  4. 通用的表結構映射所有的Class

  這種方案其實不僅支持用一張表存儲一個繼承體系,它甚至可以支持,用一張表存儲任意數(shù)量的不同Class。它的原理是元數(shù)據(jù)驅(qū)動。這張表的每一行,包含一個類型的標識字段,一個表示Class的屬性名稱的字段和一個表示Class的屬性值的字段。在運行時,通過唯一標識取出描述一個Class實例的所有Property的值,再根據(jù)Property的名稱來映射。

  關于各種繼承映射的實例分析和詳細的優(yōu)劣比較,請參見:Scott W. Ambler的O/R Mapping In Detail

  關聯(lián)映射

  1. 一對一關聯(lián)、一對多關聯(lián)(包含一對一和一對多的自關聯(lián))

  所謂一對一關聯(lián),實際上還可以分為三種情形,即0..1 - 1,1 – 1,1 – 0..1三種情形;而一對多關聯(lián)則分為* - 1和1 - *。

  以下三種方案中第1)種為最常用的映射方案,后面幾種是在某些特殊情形下可參考的方案:

  1) 最常用的方案為為需要其他對象引用的類對應的表增加一個到被引用對象對應表的外鍵即可,只不過,與表對應的實體類代碼中,對于一對多情形下的“多”這一端,需定義成集合類型;
  2) 在Hibernate稱為“組件(Component)映射”,舉例來說,假如Person類包含一個Address成員類型的屬性,而Address由City,Street,ZipCode三個成員屬性組成,假如Address除了與Person關聯(lián)不被其他對象使用,則我們可以考慮只用一張數(shù)據(jù)表Person來持久化Person和Address這兩張表,Person數(shù)據(jù)表包含Person類中除Address的屬性和Address類中的所有屬性的集合,當然,這時需要在元數(shù)據(jù)中特別指明映射關系;
  3) 還有一種針對上面的方案中的Person,Address兩個類的持久化方案則是將Address類型的所有屬性先序列化,再存入Person表的字段Address中,這樣也可以只用一張表來持久化兩個類,當然,本方案中這種被序列化對象成員數(shù)據(jù)量應盡量小;
  4) 還有一種方案是共享同一主鍵值的一對一關聯(lián)。即將原本可以同屬于一個表中相對使用不太頻繁的字段提出來放在另一張表中,這樣,這兩張表的記錄就可以通過一個相同的主鍵進行關聯(lián)。

  2. 多對多關聯(lián)(包含多對多的自關聯(lián))

  所謂多對多關聯(lián)自然就是* - *這種情形了。一般都需要一張包含關聯(lián)雙方主鍵的關聯(lián)表,在取數(shù)據(jù)時,需要鏈接該關聯(lián)表和數(shù)據(jù)表。

  英文資料

it知識庫理解O/R Mapping,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 在线亚洲黄色 | 老阿姨儿子一二三区 | 少妇一夜未归暴露妓女身份 | 99在线精品国自产拍不卡 | 小莹的性荡生活 | 亚洲一区高清 | 亚洲精品91 | 久久久久激情免费观看 | 99精品免费久久久久久久久蜜桃 | 91蜜桃视频| 国产VA精品午夜福利视频 | 快插我我好湿啊公交车上做 | 国产亚洲视频中文字幕 | 亚洲欧美日韩另类精品一区二区三区 | 伊人久久大香线蕉综合影 | 久久这里只精品热在线99 | 视频一区国产精戏刘婷30 | 暖暖日本大全免费观看 | 国产午夜精品不卡视频 | QVOD理论 | 亚洲欧美一区二区三区蜜芽 | 男生脱美女内裤内衣动态图 | 超碰97人人做人人爱亚洲尤物 | 国产亚洲精品 在线视频 香蕉 | 日韩一区二区在线免费观看 | 久色视频网 | 乌克兰粉嫩摘花第一次 | 亚洲最大在线视频 | 伊人久久综合成人亚洲 | 女人麻豆国产香蕉久久精品 | 99国产这里只有精品视频 | 亚洲 无码 制服 日韩 | 亚洲成 人a影院青久在线观看 | 国产午夜精品视频在线播放 | 中文字幕人成人乱码亚洲影视 | 国产成人久久婷婷精品流白浆 | 国产免费播放一区二区三区 | 99视频久九热精品 | 午夜精品久久久久久99热蜜桃 | 国产一区二区三区四区五在线观看 | 国产睡熟迷奷系列网站 |