2010-01-15 63 views
20

我的一位同事目前正在設計像下面這樣的SQL查詢來生成報告,這些報告通過外部顯示在excel文件中數據查詢。 目前,只需要在數據庫上報告流程(無CRUD操作)。何時使用ORM(Sequel,Datamapper,AR等)與純SQL進行查詢

我想說服他,爲了能夠在rails/sinatra應用程序中顯示數據,最好使用ruby ORM。

儘管顯示數據有明顯的優勢,但他在學習使用像Sequel或Datamapper這樣的ORM方面有什麼優勢?

他正在編寫的SQL查詢顯然非常複雜,而且對於SQL來說相對較新,他經常抱怨說這非常耗時且令人困惑。 是否可以使用ORM編寫極其復​​雜的查詢?如果是這樣,哪個是最適合的(我聽說續集對傳統dbs有好處)?在進行復雜的數據庫查詢時,學習ruby和使用ORM與堅持純SQL相比,有哪些優勢?

回答

27

我是DataMapper維護者,我認爲對於複雜的報告,您應該使用SQL。

雖然我認爲總有一天我們會有一個提供SQL的強大功能和簡潔性的DSL,但到目前爲止我看到的所有內容都要求您爲複雜查詢編寫比SQL更多的Ruby代碼。我寧願維護5行SQL查詢,而不是10-15行Ruby代碼來描述相同的複雜操作。

請注意我說複雜..如果你有簡單的東西,使用ORM的內置查找器。但是,我相信有一條線可以讓SQL變得更簡單。現在,大多數應用程序不僅僅是報告。你可能會有很多CRUD類型的操作,ORM非常適合並且比手動操作要好得多。

ORM通常會提供的一件事是某種組織到您的應用程序邏輯。您可以將基於每個模型的代碼分組到同一個文件中。它通常是在那裏我能擺出複雜的SQL查詢,而不是將它嵌入控制器,例如:

class User 
    include DataMapper::Resource 

    property :id, Serial 
    property :name, String, :length => 1..100, :required => true 
    property :age, Integer, :min => 1, :max => 130 

    def self.some_complex_query 
    repository.adapter.select <<-SQL 
     SELECT ... 
     FROM ... 
     WHERE ... 
     ... more complex stuff here ... 
    SQL 
    end 
end 

然後我就可以生成使用User.some_complex_query報告。如果您想進一步清理此代碼,您也可以將SQL查詢推入視圖。

編輯:通過上面的句子中的「視圖」,我的意思是RDBMS視圖,而不是在MVC上下文中查看。只是想澄清任何可能的混淆。

+0

我還應該注意到,我認爲ORM設計人員應該不斷研究如何進一步推動這條線,以便更簡單的查詢可以比查找SQL更簡單。我不確信我們會完全消除SQL。 – dkubb 2010-01-15 23:35:28

+0

哪個ORM最適合使用新的Rails 3應用程序與傳統的MySQL 5.1數據庫?我不希望對這個數據庫進行遷移(雖然架構可能會不時變化),但我一定會寫信給它。 – 2010-11-13 21:46:28

+1

馬克,除非你的模式匹配ActiveRecord約定,你的選擇是DataMapper和Sequel。顯然,我偏向於Datamapper,但Sequel也是一個很好的ORM。我會說,DataMapper的主要目標之一是允許它映射到傳統模式。如果您想在構建更復雜的查詢時使用類似SQL的語句,續集會更好。 – dkubb 2010-11-16 02:41:16

4

ORM代表對象關係映射 - 但看着查詢你的朋友似乎想要一個非常具體的和表和其他項目......我沒有使用Ruby的續集,但我用過Hibernate,並且Python的SQLAlchemy(用於Django/Turbogears),雖然你可以做這些查詢,但我不相信這是他們的強項。

ORM的威力來自於能夠找到Foo-> Bar對象關係,比如說你希望Foo的字段的所有Bar對象大於X ......這種事情。因此,我不會將ORM歸類爲「好」解決方案,儘管轉而使用像Ruby這樣的真正編程語言,並通過它來代替Excel來執行SQL ......這本身就是一個勝利。

只是我2美分。

6

如果您手動編寫查詢,您有機會優化它們。當我查看該查詢時,我看到了一些優化潛力(E.ICGROUPNAME LIKE'%san-fransisco%'或E.ICGROUPNAME LIKE'%bordeaux%'將不會使用索引=表掃描)。

當使用OR映射器(本地對象/表)進行報告時,您對結果SQL查詢沒有或幾乎沒有控制權。

但是:您可以將該查詢放入視圖或存儲過程中,並使用OR映射器映射該視圖/ Proc。您可以優化您的查詢您可以使用應用程序框架的所有功能。

3

在這樣的情況,我可能會用手工書寫,或用視圖(如果DB你使用支持的觀點)

5

除非你正在處理的對象,一個ORM是沒有必要的。這聽起來像你的朋友只需要生成報告,在這種情況下,只要他知道自己在做什麼(例如,避免SQL注入問題),純SQL就可以。

ORM代表「對象關係映射」。如果你沒有「O」(對象),那麼它可能不適合你的應用程序。 ORM真正發光的地方在於持久化對象到數據庫並從數據庫加載它們。

1

當你有對象(業務對象)時使用ORM。因此,我假定您有一個應用程序,您可以使用該應用程序創建和管理最終保存到數據庫中的業務對象。如果你有,那麼你幾乎可以肯定地得到關係的一些表示,並且你可能會在報告中使用很多計算。使用SQL直接訪問數據庫報告的問題只是可維護性問題。 您通常需要付出很多努力才能確保Business Objects隱藏其數據庫的任何詳細信息。您可以實施業務規則並在Business Objects中執行常見計算。爲團隊的所有成員構建一個通用語言等等。然後,您使用ORM映射到數據庫,並使用Habanero或NHibernate或類似的方法來執行此操作。這非常棒。我們以維護性的名義完成這一切,並且非常棒。你可以遷移你的應用程序,改變你的設計等等。

你現在去編寫SQL來運行報告,隨着時間的推移,你有數百個報告。首先,他們經常複製你已經在BusinessObjects中使用的邏輯(通常沒有任何測試),甚至更糟Bham Damb抱歉可維護性現在被塞滿了忘記將該字段從一個表移動到另一個表而忘記將該表分成兩個不斷變化的關係等等有一些報道會意外中斷。

通過您的域對象/業務對象查詢的問題只是性能問題之一。

總之,如果您使用的是域驅動設計或業務對象概念,請嘗試將這些用於報告。 (您可能會出於性能原因直接從數據庫運行SQL或存儲特效,但可以嘗試限制這些先使用Business Objects,然後再使用SQL)。 另一種選擇當然是使用單獨的報表數據庫(就像一些BI概念一樣)因此,從事務數據庫到報表數據庫的映射集中在一個地方,並且在需要更改設計的情況下可輕鬆更改。

域對象(Business Objects)和ORM具有所有的知識,允許您在使用域術語的同時開始構建直接在數據庫上運行的高性能查詢。讓我們希望這些繼續發展到現實。

在此之前,如果您在應用程序中使用Business Objects,請嘗試將它們用於報告,以便在性能問題上訴諸於SQL。