21

我的一位同事目前正在设计如下所示的 SQL 查询来生成报告,这些报告通过外部数据查询显示在 excel 文件中。目前,只需要数据库上的报告过程(不需要 CRUD 操作)。

我试图说服他最好使用 ruby​​ ORM 以便能够在 rails/sinatra 应用程序中显示数据。

尽管在显示数据方面优势明显,但他在学习使用 Sequel 或 Datamapper 之类的 ORM 方面有什么优势?

他正在编写的 SQL 查询显然相当复杂,而且对于 SQL 来说相对较新,他经常抱怨它非常耗时且令人困惑。是否可以使用 ORM 编写极其复​​杂的查询?如果是这样,哪个最合适(我听说 Sequel 对遗留数据库有好处)?在进行复杂的数据库查询时,学习 ruby​​ 和使用 ORM 与坚持使用普通 SQL 相比有什么优势?

4

6 回答 6

29

我是 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 上下文中的视图。只是想清除任何潜在的混乱。

于 2010-01-15T23:33:24.717 回答
6

如果您是手动编写查询,则有机会对其进行优化。当我查看该查询时,我看到了一些优化的潜力(E.ICGROUPNAME LIKE '%san-fransisco%' 或 E.ICGROUPNAME LIKE '%bordeaux%' 不会使用索引 = 表扫描)。

当使用 OR 映射器(本机对象/表)进行报告时,您对生成的 SQL 查询没有或几乎没有控制权。

但是:您可以将该查询放在视图或存储过程中,并使用 OR 映射器映射该视图/过程。您可以优化查询,并且可以使用应用程序框架的所有功能。

于 2010-01-15T17:39:32.317 回答
5

除非您正在处理对象,否则不需要 ORM。听起来您的朋友只需要生成报告,在这种情况下,只要他知道自己在做什么,纯 SQL 就可以了(例如,避免 SQL 注入问题)。

ORM 代表“对象-关系映射”。如果您没有“O”(对象),那么它可能不适合您的应用程序。ORM 真正闪耀的地方在于将对象持久化到数据库并从数据库中加载它们。

于 2010-01-15T17:43:56.107 回答
4

ORM 代表 Object Relational Mapping - 但是查看查询你的朋友似乎想要一个非常具体的总和和其他项目表......我没有使用过 Ruby 的 Sequel,但我使用过 Hibernate 和 Python 的 SQLAlchemy(对于Django/Turbogears),虽然你可以做这些类型的查询,但我不相信这是他们的强项。

ORM 的强大之处在于能够找到 Foo->Bar 对象关系,假设您希望 Foo 字段的所有 Bar 对象都大于 X... 诸如此类。因此,我不会将 ORM 归类为“好”解决方案,尽管转向像 Ruby 这样的真正编程语言并通过它而不是 Excel 执行 SQL ......这本身就是一个胜利。

只是我的2美分。

于 2010-01-15T17:34:03.677 回答
3

在这种情况下,我可能会手动编写它们或使用视图(如果您使用的数据库支持视图)

于 2010-01-15T17:43:28.190 回答
1

当您有对象(业务对象)时使用 ORM。因此,我假设您有一个应用程序,您可以使用该应用程序创建和管理最终保存到数据库中的业务对象。如果你有,那么你几乎肯定有一些关系的表示,可能还有你将在报告中使用的许多计算。使用 SQL 直接访问数据库以获取报告的问题只是可维护性。您通常会付出很多努力来确保您的业务对象隐藏其数据库的任何细节。您在业务对象中实施业务规则并进行常见计算。为团队的所有成员等建立一种通用语言。然后使用 ORM 映射到数据库并使用Habanero或 NHibernate 或类似的东西来做到这一点。这一切都很棒。我们以可维护性的名义做这一切,非常棒。您可以迁移您的应用程序更改您的设计等。

你现在去编写 SQL 来运行报告,随着时间的推移你有数百个报告。首先,他们经常重复您在 BusinessObjects 中已经拥有的逻辑(通常没有任何测试),更糟糕的是,Bham Damb 抱歉,可维护性现在被塞满了忘记将该字段从一个表移动到另一个表忘记将该表分成两个更改该关系等等有许多报告会意外中断。

查询域对象/业务对象的问题只是性能之一。

总之,如果您使用领域驱动设计或业务对象概念,请尝试将这些用于报告。(出于性能原因,您可能会使用 SQL 或存储过程直接从数据库运行,但请尝试限制这些首先使用您的业务对象,然后再使用 SQL)。当然,另一种选择是使用单独的报告数据库(如某些 BI 概念)。因此,从事务数据库到报告数据库的映射在一个地方,并且在您想要更改设计的情况下很容易更改。

域对象(业务对象)和 ORM 拥有所有知识,可让您在使用域术语时开始构建直接在数据库上运行的高性能查询。让我们希望这些继续发展到成为现实的地步。

在那之前,如果您在应用程序中使用业务对象,请尝试将它们用于报告,当性能成为问题时求助于 SQL。

于 2010-01-27T18:49:48.233 回答