久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

對象和數(shù)據(jù)庫的天然阻抗

 木有銀 2011-10-19
在“面向?qū)ο蠼Ec數(shù)據(jù)庫建模兩種分析設(shè)計(jì)方法的比較”一文中我們比較了在對需求分析時(shí)兩種方法的不同,,所謂數(shù)據(jù)庫建模分析,就是項(xiàng)目一開始就根據(jù)需求建立數(shù)據(jù)庫模型,,如數(shù)據(jù)表結(jié)構(gòu)和字段等,,這種錯(cuò)誤現(xiàn)象大量普遍存在我們國內(nèi)項(xiàng)目實(shí)踐中,從每年大量招聘啟示中就可見一斑:招聘數(shù)據(jù)庫建模人員,,招聘Java面向?qū)ο蟪绦騿T,。這些說明軟件業(yè)一邊在大量使用Java/.NET/Ruby on Rails這樣OO語言同時(shí),還在同時(shí)使用與OO體系抵觸的圍繞關(guān)系數(shù)據(jù)庫的分析設(shè)計(jì)方法,。

  為進(jìn)一步說明OO和關(guān)系數(shù)據(jù)庫是屬于兩個(gè)不同世界觀,,存在天然矛盾,就象有神論和無神論,,就象水與火那樣屬于截然相反的兩種編程知識(shí),。正好最近TheServerSide刊登一篇大談對象數(shù)據(jù)庫ODBMS的文章:When to use an Embedded ODBMS(以下簡稱ODBMS一文)
http://www./tt/articles/article.tss?l=EmbeddedODBMS

  這篇文章不但談到了OO和關(guān)系數(shù)據(jù)庫天然阻抗;談到了ODBMS和RDBMS區(qū)別,,也談到了ODBMS和O/R Mapping如Hibernate的區(qū)別,甚至談到了ODBMS在非C/S如嵌入式方面的優(yōu)點(diǎn),。這篇文章我看最重要價(jià)值就是它用大量篇幅闡述了對象和關(guān)系數(shù)據(jù)庫存在的天然矛盾,,我這里就將這部分篇幅大意轉(zhuǎn)載這里,可以說是經(jīng)過我咀嚼后反饋的結(jié)果,,版權(quán)思想還是屬于這篇文章,,我這里只是用中國人更易于接受方式把這個(gè)天然矛盾轉(zhuǎn)述出來:

對象和關(guān)系數(shù)據(jù)庫累贅轉(zhuǎn)換

  在一個(gè)面向?qū)ο笙到y(tǒng)中,數(shù)據(jù)存在于對象中,,在關(guān)系數(shù)據(jù)庫中,,數(shù)據(jù)存在于數(shù)據(jù)表的記錄中。
在關(guān)系數(shù)據(jù)庫世界中,,我們必須掌握表結(jié)構(gòu),、表記錄等概念,這里面沒有任何對象概念,,當(dāng)我們在OO語言中使用關(guān)系數(shù)據(jù)庫時(shí),,因?yàn)樵贠O世界中是大量對象,所以必須將數(shù)據(jù)在這兩個(gè)不同世界之間轉(zhuǎn)換傳輸。

   這就導(dǎo)致了大量垃圾臨時(shí)對象,,增加了應(yīng)用系統(tǒng)的復(fù)雜性,。這也是我們很多人使用了Java等這樣的OO系統(tǒng)后,反而覺得開發(fā)效率并沒有OO宣傳那么高的原因,, 說白了,,OO思想沒有完全占領(lǐng)應(yīng)用系統(tǒng),因?yàn)橛嘘P(guān)系數(shù)據(jù)庫盤踞著數(shù)據(jù)庫這個(gè)最后堡壘負(fù)隅頑抗,。

  下面看看我們程序如何為了讓OO語言和關(guān)系數(shù)據(jù)庫捆綁在一起工作,,如何彌補(bǔ)兩個(gè)世界的裂縫,如何在他們之間和稀泥,。 為了將對象保存到關(guān)系數(shù)據(jù)庫中,,我們必須將對象中的數(shù)據(jù)解散開來,再將它們組裝到SQL中,,然后執(zhí)行SQL,。
一個(gè)類如下:


public class Course {
  public string name;
  public int courseID;
  int deptID;
  public int creditHours;
}

將上述對象保存到關(guān)系數(shù)據(jù)庫的SQL語句如下:


PreparedStatement insertStatement = connection.prepareStatement(
"INSERT INTO Courses (name, courseID, deptID, creditHourse) " +
"VALUES (?, ?, ?, ?)");
insertStatement.setString(1, course.name);
insertStatement.setInt(2, course.courseID);
insertStatement.setInt(3, course.deprtID);
insertStatement.setInt(4, course.creditHours);
insertStatement.executeUpdate();

上述在兩個(gè)世界之間做的翻譯工作與復(fù)雜性取決于對象Course這樣的復(fù)雜性。如果Course字段有十幾個(gè),,那么這個(gè)保存SQL將更復(fù)雜,。

   更重要的是,萬一有一個(gè)字段發(fā)生變化,,更改量就很大,。我們不但要修改對象,而且還要修改數(shù)據(jù)表結(jié)構(gòu),,有過數(shù)據(jù)庫編程經(jīng)驗(yàn)的人知道,,如果表中有數(shù)據(jù),表結(jié)構(gòu)變動(dòng)帶來的問題可能就象噩夢一樣,,所以,,我們程序員經(jīng)常以這個(gè)需要更改表結(jié)構(gòu)拒絕一些軟件的維護(hù)和拓展,這其實(shí)更是錯(cuò)上加錯(cuò),;在ODBMS一文中提出了對象數(shù)據(jù)庫解決方案:只要更改類結(jié)構(gòu),,其他都有ODBMS搞定;使用ORM如Hibernate也只多一個(gè)步驟:更改映射配置,。

繼承關(guān)系的尷尬實(shí)現(xiàn)

  對象和關(guān)系數(shù)據(jù)庫的不匹配還表現(xiàn)在關(guān)系數(shù)據(jù)庫難以實(shí)現(xiàn)對象世界中的繼承關(guān)系,,如下圖:

extend

  這是一個(gè)典型的對象世界表達(dá)客觀世界的類圖,學(xué)生和教授都是人,,都具備人一些共性,,當(dāng)然他們之間也有區(qū)別,所以我們用上述繼承關(guān)系來表達(dá)這樣一個(gè)情況,。

  那么如果這樣繼承關(guān)系的類圖如何保存到關(guān)系數(shù)據(jù)庫中呢,?有兩種方式:one-class-per-table(一個(gè)類對應(yīng)一個(gè)表)和one-object-per-row(一個(gè)對象對應(yīng)一個(gè)表行),。

  在one-class-per-table方式中,Student對象放在Student表中,,Professor放在Professor表中,。但是Student和Professor實(shí)際具有共性Person,這實(shí)際上將Person這個(gè)共性對象中數(shù)據(jù)分割成兩個(gè)表保存,,從語義上所:也就是將一個(gè)對象分割成兩個(gè)部分了,;而且當(dāng)你要獲取這個(gè)對象時(shí),需要兩次Select,。同樣道理增刪改查都要兩次,。

  如果按照one-object-per-row,將這Student和Professor放到一個(gè)表中,,就會(huì)產(chǎn)生空白字段,。Student對象中數(shù)據(jù)保存到Student對象對應(yīng)的字段中,那么Professor對象對應(yīng)的字段就是空的,,反之也然,。

  這些都反映了對象和關(guān)系數(shù)據(jù)庫天然不匹配,兩者根本就無法搭配在一起工作,,只有一方作出妥協(xié),,大部分情況是對象作出妥協(xié),這樣,,一個(gè)OO語言Java/.NET系統(tǒng)就做成了一個(gè)數(shù)據(jù)庫中心系統(tǒng),,根本無法享受OO語言帶來快捷方便,可維護(hù)性強(qiáng),,由于Java出現(xiàn)比較早,,更多程序員將項(xiàng)目失敗歸結(jié)于Java語言本身,轉(zhuǎn)而使用數(shù)據(jù)庫思維去做.NET,,去做Ruby On Rails,,還是會(huì)碰到上面這些問題,沒有碰到,,只能說明他們系統(tǒng)中就沒有對象概念,解決方式很簡單很可笑:矛盾雙方,,消滅一方不久解決矛盾了,。

類的復(fù)雜關(guān)系實(shí)現(xiàn)

  下面我們再看看ODBMS一文中列舉的類復(fù)雜關(guān)系如何用關(guān)系數(shù)據(jù)庫實(shí)現(xiàn)保存:


public class Department {
    private Professor[] professors;
... }

  這個(gè)Department類很明確告訴我們這樣一個(gè)意思,在一個(gè)Department中,,存在很多Professor,,大白話就是:一個(gè)部門里有很多教授,這個(gè)類就自然準(zhǔn)確地表達(dá)這個(gè)意思,,這也體現(xiàn)了使用OO表達(dá)需求的自然性和方便性,。

  那么我們下面看看,如果我們使用關(guān)系數(shù)據(jù)庫來保存Department這個(gè)對象,很顯然,,這里需要使用關(guān)系數(shù)據(jù)庫的表外鍵,,通過表外鍵來表達(dá)Department表和Professor之間1:N關(guān)系,關(guān)鍵問題是:這個(gè)外鍵一般是設(shè)計(jì)在Professor表中,,這就造成語義上的誤解,。

  對象Department表達(dá)的需求含義是:
  1. 我是一個(gè)部門對象,在我里面包含很多教授對象,。

  當(dāng)這個(gè)對象在關(guān)系數(shù)據(jù)庫,,由于外鍵在Professor表中,那么意思就是:
  2. 我是一個(gè)教授對象,,這里有一個(gè)我所屬的部門對象,。

  前后對比發(fā)現(xiàn),其實(shí)完全是兩者不同表達(dá)方式,,這已經(jīng)屬于拷貝走樣了,,當(dāng)我們從關(guān)系數(shù)據(jù)庫中獲得Department 對象時(shí),得按照關(guān)系數(shù)據(jù)庫規(guī)則繞一個(gè)彎來獲得完整的Department 對象,。也就是說:每次獲得一個(gè)對象Department,,我們得將這個(gè)需求意思翻譯成關(guān)系數(shù)據(jù)庫的表達(dá)方式,這種內(nèi)耗式的翻譯不但容易出錯(cuò),,也帶來了程序員開發(fā)上的負(fù)擔(dān),。萬一不留神,翻譯出錯(cuò),,問題就嚴(yán)重了,。

  當(dāng)然,如果我們使用ODBMS,,就不必做這些費(fèi)力不討好的翻譯轉(zhuǎn)換,,也不再繞著彎子編程,只要直接告訴ODBMS或ORM框架如Hibernate,,就能夠獲得一個(gè)真正對象意義上的Department,。

  以上是TSS的ODBMS一文大量篇幅闡述了對象和關(guān)系數(shù)據(jù)庫矛盾的方面,所以,,我們才認(rèn)為:如果你使用對象語言,,如Java/.NET/Ruby On Rails等,那么就必須堅(jiān)持OO思想和方法,,從程序中杜絕關(guān)系數(shù)據(jù)庫對軟件的影響,,將關(guān)系數(shù)據(jù)庫只看成是活動(dòng)對象的“冬眠”(英文Hibernate)地方,這也就是ORM框架Hibernate的本義所在,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多