成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

為什么說ORM是一種反模式

PingCAP / 2451人閱讀

摘要:什么是反模式我很高興地發(fā)現(xiàn)有一個相當(dāng)全面的關(guān)于反模式的列表,包括來自編程界及其之外的內(nèi)容。但是要作為一個反模式,還需要存在替代的解決辦法。

上周我在twitter上討論了ORM,在那以后有人希望我澄清一下。事實(shí)上,我曾經(jīng)寫文章討論過ORM,?但那是時的上下文是關(guān)于SQL的,我不應(yīng)該把這將兩件事情混為一談。

因此,在本文中我將集中討論ORM本身。同時,我盡力保持簡潔,因為我從自己的SQL文章中發(fā)現(xiàn):人們一旦讀到讓他們發(fā)怒的內(nèi)容就很容易離開(同時留下一句評論,而不論他們所關(guān)注的東西是否在后面會討論到)。

什么是反模式?

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

它開始的時候看起來很有用,但是從長期來看,壞處要大過好處

存在已驗證并且可重復(fù)的替代方案

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

這對ORM來說是什么意思?

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

ORM的優(yōu)點(diǎn)

簡單:一些ORM層告訴你它們“消除了對SQL的要求”。我至今仍然看到這種承諾在傳播。其他一些會更加現(xiàn)實(shí)地聲稱它們可以減少手寫SQL的需要,但是仍然允許你在需要的時候使用它。對于簡單的模型以及項目的早期,這確實(shí)是一個優(yōu)點(diǎn):使用ORM,無疑你能夠更快地開始啟動。然而,你將會走向錯誤的方向。

代碼生成:使用ORM從模型中消除用戶層面的代碼,這一做法開啟了通向代碼生成的大門。通過對schema的簡單描述,“腳手架”模式可以為你的所有表生成一個可工作的界面。更加具有魔力的是,你可以修改你的schema描述,然后重新生成代碼,從而消除了CRUD。同樣,這在開始的時候確實(shí)是可行的。

性能“足夠好”:我沒有看到任何ORM層聲稱在性能上更加優(yōu)越。很明顯,為了代碼的敏捷性需要付出性能的代碼。如果哪里變慢了,你總是可以用更加有效的手寫SQL覆蓋你的ORM方法。不是嗎?

ORM的問題

不充分的抽象

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

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

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

不正確的抽象

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

但是,如果你的數(shù)據(jù)不是關(guān)系型的,那么你就是在不適當(dāng)?shù)膱龊鲜褂肧QL,這為你增加了巨大且不必要的負(fù)擔(dān);為了讓問題更加嚴(yán)重,你在其上又增加了一重額外的抽象。

另一方面,如果你的數(shù)據(jù)是關(guān)系型的,那么你的對象映射最終會失敗。SQL是關(guān)于關(guān)系代數(shù)的:SQL的輸出不是對象,而是對于某個問題的解答。如果你的對象“是一個”X的實(shí)例,并且“擁有一些”Y,且每個Y“屬于”Z,那么對象在內(nèi)存中正確的表達(dá)形式是什么?

它應(yīng)該是X的屬性,或者全部包含在Y中,或者/并且全部包含在Z中?如果你只得到X的屬性,那么何時你運(yùn)行查詢來獲得Y呢?而且,你是想要其中一個還是全部?現(xiàn)實(shí)中,答案是依賴于條件的:這就是為什么我說SQL是對于問題的回答。對象在內(nèi)存中的表達(dá)形式取決于你的意圖,然而面向?qū)ο笤O(shè)計沒有依賴于上下文的表達(dá)這樣的功能。關(guān)系不是對象;對象也不是關(guān)系。

多個查詢導(dǎo)致失敗

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

那么替代方案是什么?
希望到這里我已經(jīng)澄清ORM在設(shè)計上的一些缺陷。但是要作為一個反模式,還需要存在替代的解決辦法。事實(shí)上有兩個取代方法:

使用對象

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

在模型中使用SQL

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

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

總結(jié)

ORM最初比編寫基于SQL的模型代碼更快,也更容易理解

它在任何項目早期都是足夠有效的

不幸的是,這些優(yōu)點(diǎn)在項目復(fù)雜性提升的時候就消失了:抽象被打破,開發(fā)者被迫使用并理解SQL

完全是非正式的聲明,我認(rèn)為ORM對抽象的破壞不是僅僅涉及20%的項目,而是幾乎100%。

對象并不足以充分表達(dá)關(guān)系查詢的結(jié)果。

關(guān)系查詢映射到對象的不充分性導(dǎo)致了ORM后端應(yīng)用的效率低下,這些問題普遍分布在應(yīng)用的各處,并且除了完全放棄ORM之外,沒有簡單的解決辦法。

不要對任何問題都使用關(guān)系存儲與ORM,而是更加仔細(xì)地思考你的設(shè)計

如果你的數(shù)據(jù)天生就是對象,那么請使用對象存儲("NoSQL")。它們要比關(guān)系數(shù)據(jù)庫快得多。

如果你的數(shù)據(jù)天生就是關(guān)系型的,那么關(guān)系數(shù)據(jù)庫帶來的開銷是值得的。

把你的關(guān)系查詢封裝在模型層中,設(shè)計你的API從而為應(yīng)用提供數(shù)據(jù)訪問支持;拒絕過分泛化的誘惑。

面向?qū)ο鬅o法以有效的形式表達(dá)關(guān)系數(shù)據(jù);這是面向?qū)ο笤O(shè)計的一個基本限制,ORM無法修復(fù)它。


原文 ORM is an anti-pattern
轉(zhuǎn)自 nowamagic.net

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/17435.html

相關(guān)文章

  • 如何借助 NoSQL 提高 JPA 應(yīng)用性能

    摘要:當(dāng)時,還飽受微軟和太陽間的訴訟的影響,該訴訟涉及到和間的兼容性。開發(fā)者們都在討論哪個平臺或者框架能夠勝出還是微軟新發(fā)布的。能為您提供端到端的應(yīng)用性能解決方案,我們支持所有常見的框架及應(yīng)用服務(wù)器,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸,定位異常根本原因。 【編者按】關(guān)注 NoSQL 的動態(tài)發(fā)展很重要。NoSQL 的好處并不僅限于新的應(yīng)用開發(fā)。在某些案例中,你可以見識到重新訪問現(xiàn)有的、傳統(tǒng)的框架帶來的積極效...

    Airy 評論0 收藏0
  • [譯] 設(shè)計一個容錯的微服務(wù)架構(gòu)

    摘要:微服務(wù)架構(gòu)的風(fēng)險微服務(wù)架構(gòu)將應(yīng)用程序邏輯移動到服務(wù),并使用網(wǎng)絡(luò)層在它們之間進(jìn)行通信。在微服務(wù)架構(gòu)中,服務(wù)依賴于彼此。您始終只能部署其中一個,并且在驗證新版本是否符合預(yù)期之后才,將負(fù)載均衡器指向新的。 [譯] 設(shè)計一個容錯的微服務(wù)架構(gòu) 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog 原文地址 https://blog....

    raledong 評論0 收藏0
  • 大話微服務(wù)架構(gòu)故障隔離及容錯處理機(jī)制

    摘要:優(yōu)雅的服務(wù)降級微服務(wù)架構(gòu)最大的優(yōu)點(diǎn)之一就是當(dāng)組件出現(xiàn)故障時,能隔離這些故障并且能做到優(yōu)雅地服務(wù)降級。 本文首先介紹微服務(wù)架構(gòu)存在的風(fēng)險,然后針對如何避免微服務(wù)架構(gòu)的故障,提出了多種有效的微服務(wù)架構(gòu)中的方法和技術(shù),其中例如服務(wù)降級、變更管理、健康檢查和修復(fù)、斷路器、限流器等。 目錄 1、微服務(wù)架構(gòu)的風(fēng)險 2、優(yōu)雅的服務(wù)降級 3、變更管理 4、健康檢查和負(fù)載均衡 5、自我修復(fù) 6、故障轉(zhuǎn)移...

    Binguner 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<