2010-01-15 66 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。