• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    為什么我說ORM是一種反模式

    來源:懂視網 責編:小采 時間:2020-11-09 13:37:01
    文檔

    為什么我說ORM是一種反模式

    為什么我說ORM是一種反模式:上周我在在上討論了ORM,在那以后有人希望我澄清我的意思。事實上,我曾經寫文章討論過ORM,但那是在一場關于SQL的大討論的上下文中,我不應該把這將兩件事情混為一談。 因此,在本文中我將關注ORM本身。同時,我盡力保持簡略,因為從我的SQL文章中顯而易見
    推薦度:
    導讀為什么我說ORM是一種反模式:上周我在在上討論了ORM,在那以后有人希望我澄清我的意思。事實上,我曾經寫文章討論過ORM,但那是在一場關于SQL的大討論的上下文中,我不應該把這將兩件事情混為一談。 因此,在本文中我將關注ORM本身。同時,我盡力保持簡略,因為從我的SQL文章中顯而易見

    上周我在在上討論了ORM,在那以后有人希望我澄清我的意思。事實上,我曾經寫文章討論過ORM,?但那是在一場關于SQL的大討論的上下文中,我不應該把這將兩件事情混為一談。 因此,在本文中我將關注ORM本身。同時,我盡力保持簡略,因為從我的SQL文章中顯而易見

    上周我在在上討論了ORM,在那以后有人希望我澄清我的意思。事實上,我曾經寫文章討論過ORM,?但那是在一場關于SQL的大討論的上下文中,我不應該把這將兩件事情混為一談。 因此,在本文中我將關注ORM本身。同時,我盡力保持簡略,因為從我的SQL文章中顯而易見的是:人們傾向于一旦讀到讓他們發怒的內容就會離開(同時留下一句留言,而不論他們所關注的東西是否在后面會討論到)。

    什么是反模式?

    我很高興地發現Wikipedia有一個相當全面的關于反模式的列表,包括來自編程界及其之外的內容。我之所以稱ORM為反模式的原因是因為,反模式的作者定義了用來區分反模式和普通的壞習慣的兩個條件,而ORM完全符合這些條件:

    1. 它開始的時候看起來很有用,但是從長期來看,壞處要大過好處
    2. 存在已驗證并且可重復的替代方案

    由于第一個因素導致了ORM令人抓狂(對我來說)的流行性:它第一眼看上去像是個好主意,但是當問題更加明顯的時候,已經很難離開了。

    這對ORM來說是什么意思?

    我想說的主要問題在于?ActiveRecord,它由于 Ruby on Rails 而著名, 從那以后已經移植到了許多其他語言。然而,這些問題同樣存在于其他的ORM層,比如Java的Hibernate和PHP的Doctrine。

    ORM的優點

  • 簡單:一些ORM層告訴你它們“消除了對SQL的要求”。我至今仍然看到這種承諾在傳播。其他一些會更加現實地聲稱它們可以減少手寫SQL的需要,但是仍然允許你在需要的時候使用它。對于簡單的模型以及項目的早期,這確實是一個優點:使用ORM,無疑你能夠更快地開始啟動。然而,你將會走向錯誤的方向。
  • 代碼生成:使用ORM從模型中消除用戶層面的代碼,這一做法開啟了通向代碼生成的大門。通過對schema的簡單描述,“腳手架”模式可以為你的所有表生成一個可工作的界面。更加具有魔力的是,你可以修改你的schema描述,然后重新生成代碼,從而消除了CRUD。同樣,這在開始的時候確實是可行的。
  • 性能“足夠好”:我沒有看到任何ORM層聲稱在性能上更加優越。很明顯,為了代碼的敏捷性需要付出性能的代碼。如果哪里變慢了,你總是可以用更加有效的手寫SQL覆蓋你的ORM方法。不是嗎?
  • ORM的問題

    1. 不充分的抽象

    ORM最明顯的問題是它并不能完全從實現細節中抽象出來。所有主流ORM的文檔中到處都引用了SQL的概念。其中一些介紹的時候并不會表明其在SQL中的等價物,而其他一些則將庫看作用來生成SQL的過程函數。

    抽象的要點在于它應該使問題得以簡化。對SQL進行抽象,同時又要求你懂得SQL,這使得你需要學習的東西成倍增加了:首先,你必須理解你正在試圖執行的SQL是什么,然后你還要學習ORM的API,來讓它為你編寫這些SQL。在Hibernate中,為了完成復雜的SQL你甚至需要學第三種語言:HQL,它幾乎就是SQL(但又不完全是),其在幕后被翻譯成SQL。

    ORM的支持者會辯解說并非每個項目都是如此,并非每個人都需要復雜的join,并且ORM是一個"80/20"解決方案,其中80%的用戶只需要SQL中20%的功能,ORM可以處理這些問題。我能說的是,我15年來編寫web應用的數據庫后端的經歷表明,事實并非如此。只有在項目剛開始的時候你不需要join和本地join。在那之后,你就要優化和鞏固你的查詢。即使80%的用戶只用到SQL中30%的功能,可是100%的用戶都需要打破ORM的抽象才能夠完成工作。

    2. 不正確的抽象

    如果你的項目確實不需要任何關系數據功能,那么ORM可以非常完美地為你工作。但是接下來你又遇到另外一個問題:你用錯了了數據存儲。關系存儲的額外付出是非常高的;這就是為什么NoSQL數據要快得多的重要原因之一。然而,如果你的數據是關系型的,那么額外的付出就是值得的:你的數據庫不僅存儲數據,它還表達了你的數據,并且可以基于關系概念回答關于它的問題,這比你用過程代碼能夠做到的要快速得多。

    但是,如果你的數據不是關系型的,那么你就是在不適當的場合使用SQL,這為你增加了巨大且不必要的負擔;為了讓問題更加嚴重,你在其上又增加了一重額外的抽象。

    另一方面,如果你的數據是關系型的,那么你的對象映射最終會失敗。SQL是關于關系代數的:SQL的輸出不是對象,而是對于某個問題的解答。如果你的對象“是一個”X的實例,并且“擁有一些”Y,且每個Y“屬于”Z,那么對象在內存中正確的表達形式是什么? 它應該是X的屬性,或者全部包含在Y中,或者/并且全部包含在Z中?如果你只得到X的屬性,那么何時你運行查詢來獲得Y呢?而且,你是想要其中一個還是全部?現實中,答案是依賴于條件的:這就是為什么我說SQL是對于問題的回答。對象在內存中的表達形式取決于你的意圖,然而面向對象設計沒有依賴于上下文的表達這樣的功能。關系不是對象;對象也不是關系。

    3. 多個查詢導致失敗

    這自然的引出了ORM的另一個問題:效率低下。當你獲取一個時,你需要哪些屬性?ORM并不知道,所以它總是取得全部(或者它要求你告訴它,但是這又打破了抽象)。開始的時候這不成問題,但是當你一次取出上千條紀錄的時候,如果你只需要3個屬性卻不得不取出全部30列,這時就產生了嚴重的性能問題。許多ORM層非常不善于推斷join,從而不得不使用分離的查詢來獲取關聯數據。如前所述,許多ORM層明確聲明效率將會有所犧牲,其中一些提供了某些機制來調整引起問題的查詢。我從過去的經歷中發現的問題表明,很少有只需要調整單個“銀彈”查詢的情況:應用的數據庫后端之所以死掉不是因為其中某一條查詢,而是眾多的查詢引起的。ORM缺少上下文敏感的性質意味著它無法鞏固查詢,相反必須借助cache或其他機制來進行一定程度的補償。

    那么替代方案是什么?

    希望到這里我已經澄清ORM在設計上的一些缺陷。但是要作為一個反模式,還需要存在替代的解決辦法。事實上有兩個取代方法:

    1. 使用對象

    如果你的數據是對象,那么停止使用關系數據庫。編程界當前正在出現鍵-值對存儲的浪潮,它允許你以閃電般的速度訪問優雅的、自我包含的海量數據。沒有法律規定編寫Web應用的第一步必須安裝MySQL。對于對象的每一種表達方式都使用關系數據庫是一種過度使用,這也是近幾年SQL的名稱不太好的原因之一。事實上,問題在于偷懶的設計。

    2. 在模型中使用SQL

    編程中作任何事情都只有一種正確的方式,這是一種危險的說法。然而根據我的實踐,在面向對象的代碼中表達關系模型的最佳方法仍然是模型層:將你的所有數據表示封裝在一個單獨的區域是一個好注意。然而,記住模型層的工作簿在于表達對象,而在于回答問題。提供一個可以回答你的應用程序所包含的問題的API,盡量保持簡潔高效。有時候,這些回答顯得格格不入,以致于看上去是“錯誤的”,甚至對于資深的OO開發者也是如此。但是,你可以根據經驗來更好地找到其中的普遍性,從而允許你將多個查詢方法重構為單個。

    類似的,有時候輸出會是單個對象X,它很容易表達。 但是也有時候輸出是聚合的對象表格,或者單個整數值。你要忍住將這些內容用過多抽象來包裝的誘惑,用對象自身的術語來描述。首要的是,不要相信OO能夠表達任何對象和所有對象。OO本身是一種優美和靈活的抽象,但關系數據在其范圍之外,把它不能表達的東西偽裝成對象是ORM的核心與真正的問題。

    總結

  • ORM最初比編寫基于SQL的模型代碼更快,也更容易理解
  • 它在任何項目早期都是足夠有效的
  • 不幸的是,這些優點在項目復雜性提升的時候就消失了:抽象被打破,開發者被迫使用并理解SQL
  • 完全是非正式的聲明,我認為ORM對抽象的破壞不是僅僅涉及20%的項目,而是幾乎100%。
  • 對象并不足以充分表達關系查詢的結果。
  • 關系查詢映射到對象的不充分性導致了ORM后端應用的效率低下,這些問題普遍分布在應用的各處,并且除了完全放棄ORM之外,沒有簡單的解決辦法。
  • 不要對任何問題都使用關系存儲與ORM,而是更加仔細地思考你的設計
  • 如果你的數據天生就是對象,那么請使用對象存儲("NoSQL")。它們要比關系數據庫快得多。
  • 如果你的數據天生就是關系型的,那么關系數據庫帶來的開銷是值得的。
  • 把你的關系查詢封裝在模型層中,設計你的API從而為應用提供數據訪問支持;拒絕過分泛化的誘惑。
  • 面向對象無法以有效的形式表達關系數據;這是面向對象設計的一個基本限制,ORM無法修復它。
  • 聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    為什么我說ORM是一種反模式

    為什么我說ORM是一種反模式:上周我在在上討論了ORM,在那以后有人希望我澄清我的意思。事實上,我曾經寫文章討論過ORM,但那是在一場關于SQL的大討論的上下文中,我不應該把這將兩件事情混為一談。 因此,在本文中我將關注ORM本身。同時,我盡力保持簡略,因為從我的SQL文章中顯而易見
    推薦度:
    標簽: 為什么 模式 一種
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 免费精品一区二区三区第35 | 国产精品www| 久久精品国产99国产精品| 99re热视频这里只精品| 在线精品亚洲| 久久精品?ⅴ无码中文字幕| segui久久国产精品| 国产92成人精品视频免费| 香蕉久久夜色精品升级完成| 国产午夜精品一区二区三区小说 | 国产高清精品在线| 国产精品一级香蕉一区| 精品乱码一区二区三区四区| 亚洲精品乱码久久久久久按摩 | 99在线精品免费视频九九视| 伊人精品久久久久7777| 久久久久国产精品三级网| 国产精品高清2021在线| 免费欧美精品a在线| 国产精品视频久久久| 99re6这里有精品热视频| 无码人妻精品一区二区三| 欧美精品整片300页| 精品国产一区二区三区2021| 国产精品福利片免费看| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 无码精品国产一区二区三区免费| 日韩精品无码人妻一区二区三区| 国产精品自在拍一区二区不卡| 亚洲精品在线观看视频| 热久久这里只有精品| 国产原创精品视频| 精品一区二区三区四区| 久久国产精品99久久久久久老狼| 国产精品影音先锋| 精品少妇一区二区三区视频| 国产精品久久久久久久| 精品亚洲一区二区| 97久人人做人人妻人人玩精品| 91精品啪在线观看国产电影| 99在线观看视频免费精品9|