爲何不推崇複雜的ORM

      上一篇文章寫完,回覆的人不少,有的說的很中肯,有的貌似只是看到文章的標題就進來寫評論的!還有人問爲何我要屏蔽掉【反對】按鈕,由於誰寫文章都是爲了分享,都在說出本身的心得體會。不過因爲你們遇到的項目,作的東西,見過技術各有差別,很難讓每一個人都向一種意見靠攏。因此你能夠不喜歡,可是請不要做惡!html

      評論中*深海, lindping說的是通用的ORM能夠爲通用產品帶來部署的便利!dax.net深藍醫生路過秋天說的是ORM一個很關鍵的做用就是能夠加快開發速度!還有些屬於性能控,對SQL比較推崇。還有些沒有明白表達的意圖,語文是音樂老師教的!實在抱歉!程序員

     先說下部署這個問題,若是是作通用產品的話,考慮到各類數據庫的兼容確實能帶來不少好處。這一點我很認同,不過從業開始但如今,接觸過的項目基本上都是屬於定製類的,因此這一點沒能感同身受。有過一次,不過不是換數據庫這麼簡單,而是換整個部署方案,從WINDOW平臺換到LINUX上,數據庫從MSSQL換成ORACLE。沒用ORM,用的SQLSHOP+存儲過程的方式來作的系統,先後一個星期所有完工。由於SQLSHOP的SQL都是能夠人工干涉的,存儲過程這一類的調用也是放在SQLSHOP裏面,因此咱們基本上沒有動一行代碼,都是經過機器生產和人工的方式來修改存在XML裏面的SQL,效果還能夠。也是由於此次的經歷,我才發現原來MSSQL和ORACLE其實差不了多少,存儲過程,SQL函數,調用的語法,性能等等.Mono加JEXUS,有時比IIS還給力。數據庫

      開發效率是評論中比較讓我糾結的。由於我不是說我不用ORM,而是我以爲ORM設計的太複雜,沒有什麼太大的意義(原文第四句哈)!緩存

      主流的數據庫,其增【INSERT INTO . (.,.)VALUES(.,.)】,刪【DELETE FROM . WHERE ...】,改【UPDATE . SET .=. WHERE .=.】的語法都同樣,這部分能夠抽象,作出一個支持CUD(沒有R)的系統。函數

      可是查詢就不是那麼簡單了,人們對數據的關注點不同,因此須要的查詢語句就不相同。不是全部主流數據庫都有一個相同的查詢系統,因此這一部分很難抽象。性能

      因此沒有一套ORM能很完美的處理了查詢問題。spa

      1.語法上,無法作到比SQL更簡潔。.net

      2.語義上,各庫SQL方言的差別很大。你須要爲每一個主流數據庫寫一套不一樣的SQL方言系統,你須要瞭解各類庫SQL的特色。設計

      3.語用上,你須要動態生成符合當前情景的SQL。好比你作分頁,每種庫純SQL的分頁方言就有不少,每種分頁在不一樣的分頁情景下效率是不一樣的,最優的狀況是你能夠動態去判斷情景。htm

      上述三點,不說第三點。前兩個弄得很好的ORM,開源的NHibernate沒有作到,微軟本身的EF沒有作到,商用的LightSpeed也沒有作到。目前的ORM都是在1和2上下功夫。3很難,並且對需求如此苛刻的也不會使用ORM了。因此,我卻是以爲與其活生生的坑在這三點上,倒不如從如下幾個方面好好考慮一下,數據庫支持,功能支持,語法支持,映射支持等。好比:

       1.考慮下NOSQL吧,能夠作完整單表映射或NOSQL數據的對象映射。

             怎麼支持RavenDB,STSdb,MongoDB,Cassandra等?

       2.考慮下DDD吧。功能齊全的CUD系統,可否很好的支持CQRS中C?

             怎樣快速從數據庫中映射出運行時對象?反射,EMIT,表達式?

             怎麼提升緩存的命中?支持Memcached,仍是使用本身實現的?

       3.考慮下支持OO原生特性,由於須要拿ORM來表達業務流程,是站在OO的角度考慮問題而不是數據庫。那麼你的ORM就須要考慮一些數據庫問題了。

            怎樣爲有繼承關係的對象設計表?共享同一張表,仍是分開,而後使用字段關聯?

            怎樣選擇更新時的充血或貧血?充血和貧血都有優缺點,怎樣選擇?

            業務對象是能夠用戶實例化的仍是隻能由ORM實例化?用戶實例化和ORM實例化各有各的好處,選擇哪一個?

            能否爲對象及對象的屬性添加攔截?可以知道系統中最熱對象是哪一個,最熱屬性是哪一個,由此能夠得出一些頗有意思的信息在,怎麼設計?

             ......

            這實在是太多了,不論是細節仍是宏觀上,都太多了。

       4.考慮下支持從數據庫直接映射成XML或JSON吧,或把XML或JSON直接轉換爲SQL吧,雖然XML和JSON不是對象,可是愈來愈多的地方使用XML或JSON來作對象容器。

           

      說完查詢SQL生成的複雜,再說業務邏輯的問題。把複雜邏輯放在代碼,仍是放在數據庫裏面。其實這個也很讓人糾結。站在數據庫的角度想,在離數據越近的地方處理數據越快,因此放在數據庫裏面吧。可是站在代碼的角度考慮,各類對象組合在一個表達了一套完整的業務流程,用OO的方式去考慮這個流程遠比使用數據庫表結構去表達要好不少,因此放在代碼裏面吧!......評論中地獄門神的評論很直接,我也很想這麼作。可是有時候,徹底使用代碼去完成一套業務流程是不靠譜的。使用存儲過程的時候,一切都是在數據庫中,少了從數據庫表到運行時對象的轉換,確定會快不少。並且業務流程越複雜,這一點體現的越明顯。若是你的系統中有個部分是和不少表關聯的,好比權限模塊,你用ADO.NET到OBJECT,再處理OBJECT,再使用OBJECT和ADO.NET獲取新的OBJECT的這種串行化的方式處理業務流程,當表的關聯到達必定程度的時候,那個速度是完徹底全不能忍受的。這個時候就須要使用存儲過程了。

    因此根據以往的經驗,使用存儲過程的地方主要是兩點。

    1.若是有部分的業務變化比較頻繁而且有一些性能要求,使用存儲過程吧,這樣在系統運行時就能輕鬆的修復一些問題。

    2.若是一個流程關聯的表比較多(多於3張以上的表),並且每一個表的數據都超過1W,那麼也用存儲過程吧。

    若是對性能要求不高,表關聯也很少,業務流程很簡單,那就可使用代碼的方式來表達業務流程了。

 

    因此,想一想吧!

    複雜查詢SQL,就算是再複雜的ORM也玩不來的,與其如此,倒不如設計的簡單易用些。

    不要再爲ORM考慮怎麼所有的CURD都是對象操做,怎麼所有的查詢SQL都是自動生成,怎麼設計支持多表關聯了。

    做爲程序員,何須活的那麼複雜,大道至簡! 

 

   補加一段我下午5點的評論(評論31樓)!

如今全部的ORM都是以解決對象的CURD爲目標的!

可是!
數據庫集羣的時候,讀寫分離!
CQRS中把C和Q會分開!
因此!
本來R和CUD就不是一類,可是非要用ORM來動態生成!
生成的結果又也不必定好,也不能充分體現每種數據庫本身的優點!
與其如此,倒不如把CUD作好,把R外置出去,作到能夠人爲干涉!
由於我本身一直在作ORM,也但願作的完美!
C#寫的ORM,我用過的不必定你都用過!
用的越多,本身作的時間越長就越以爲R和CUD不是一類!
因此就但願把R從ORM中外置除去,作到全部生成的SQL能夠手動干涉!
開發效率不會比你直接調ORM的SQL慢,可是效率絕對不比你慢,修改絕對比內置在ORM內部要方便,以爲那個SQL生成的很差,還能夠手動去改!
這就是把R和CUD分出去的好處!
如今的ORM,那個能作到這麼靈活!

相關文章
相關標籤/搜索