何时使用 ORM(Sequel、Datamapper、AR 等)与纯 SQL 进行查询
我的一位同事目前正在设计如下所示的 SQL 查询来生成报告,这些报告通过外部数据查询显示在 Excel 文件中。 目前,只需要数据库上的报告过程(无CRUD操作)。
我试图说服他,最好使用 ruby ORM,以便能够在 Rails/sinatra 应用程序中显示数据。
尽管在显示数据方面有明显的优势,但是学习使用 Sequel 或 Datamapper 这样的 ORM 对他来说有什么优势呢?
他正在编写的 SQL 查询显然非常复杂,而且由于对 SQL 相对较新,他经常抱怨它非常耗时且令人困惑。 是否可以使用 ORM 编写极其复杂的查询?如果是这样,哪个是最合适的(我听说 Sequel 对于遗留数据库有好处)?在进行复杂的数据库查询时,学习 Ruby 并使用 ORM 与坚持使用普通 SQL 相比有何优势?
A colleague of mine is currently designing SQL queries like the one below to produce reports, which are displayed in excel files through an external data query.
At present, only reporting processes on the DB are required (no CRUD operations).
I am trying to convince him that it would be better to use a ruby ORM in order to be able to display the data in a rails/sinatra app.
Despite the obvious advantages in displaying the data, what advantages are there for him in learning to use an ORM like Sequel or Datamapper?
The SQL queries he is writing are clearly quite complex, and being relatively new to SQL, he often complains that it is very time-consuming and confusing.
Is it possible to write extremely complex queries with an ORM? and if so, which is the most suitable(I have heard Sequel is good for legacy dbs)? and what are the advantages of learning ruby and using an ORM versus sticking with plain SQL, in making complex database queries?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我是 DataMapper 维护者,我认为对于复杂的报告,您应该使用 SQL。
虽然我确实认为有一天我们会拥有一个能够提供 SQL 的强大功能和简洁性的 DSL,但到目前为止我所看到的一切都要求您为复杂查询编写比 SQL 更多的 Ruby 代码。我宁愿维护 5 行 SQL 查询,也不愿维护 10-15 行 Ruby 代码来描述相同的复杂操作。
请注意我说的是复杂..如果你有简单的东西,请使用 ORM 的内置查找器。然而,我确实相信有一条界限可以让 SQL 变得更简单。现在,大多数应用程序不仅仅是报告。您可能有很多 CRUD 类型的操作,ORM 非常适合这些操作,并且比手动执行这些操作要好得多。
ORM 通常会提供的一件事是对应用程序逻辑进行某种组织。您可以根据同一文件中的每个模型对代码进行分组。通常我会在那里放置复杂的 SQL 查询,而不是将其嵌入到控制器中,例如:
然后我可以使用 User.some_complex_query 生成报告。如果您想进一步清理此代码,您还可以将 SQL 查询推送到视图中。
编辑:上面句子中的“视图”是指 RDBMS 视图,而不是 MVC 上下文中的视图。只是想消除任何潜在的混乱。
I'm the DataMapper maintainer, and I think for complex reporting you should use SQL.
While I do think someday we'll have a DSL that provides the power and conciseness of SQL, everything I've seen so far requires you to write more Ruby code than SQL for complex queries. I would much rather maintain a 5 line SQL query than 10-15 lines of Ruby code to describe the same complex operation.
Please note I say complex.. if you have something simple, use the ORM's build-in finders. However, I do believe there is a line you can cross where SQL becomes simpler. Now, most apps aren't just reporting. You may have alot of CRUD type operations, for which an ORM is perfectly suited and far better than doing those things by hand.
One thing that an ORM will usually provide is some sort of organization to your application logic. You can group code based around each model in the same file. It's usually there that I'll put the complex SQL query, rather than embedding it in the controller, eg:
Then I can just generate the report using
User.some_complex_query
. You could also push the SQL query into a view if you wanted to further cleanup this code.EDIT: By "view" in the above sentence I meant RDBMS view, rather than view in the MVC context. Just wanted to clear up any potential confusion.
如果您手动编写查询,您就有机会优化它们。当我查看该查询时,我发现了一些优化潜力(E.ICGROUPNAME LIKE '%san-fransisco%' 或 E.ICGROUPNAME LIKE '%bordeaux%' 不会使用索引 = 表扫描)。
当使用 OR 映射器(本机对象/表)进行报告时,您无法或很少控制生成的 SQL 查询。
但是:您可以将该查询放入视图或存储过程中,并使用 OR 映射器映射该视图/过程。您可以优化查询并且您可以使用应用程序框架的所有功能。
If you are writing your queries by hand you have the chance to optimize them. When I look at that query I see some potential for optimizations (E.ICGROUPNAME LIKE '%san-fransisco%' or E.ICGROUPNAME LIKE '%bordeaux%' wont use an index = Table Scan).
When using an OR Mapper (the native Objects/Tables) for reporting you have no or little control over the resulting SQL Query.
But: You could put that query in an View or Stored Procedure and map that View/Proc with an OR Mapper. You can optimize your queries and you can use all features of your Application Framework.
除非您正在处理对象,否则 ORM 不是必需的。听起来您的朋友只需要生成报告,在这种情况下,只要他知道自己在做什么(例如避免 SQL 注入问题),纯 SQL 就可以了。
ORM 代表“对象关系映射”。如果您没有“O”(对象),那么它可能不太适合您的应用程序。 ORM 真正出色的地方在于将对象持久保存到数据库并从数据库加载它们。
Unless you're dealing with objects, an ORM is not necessary. It sounds like your friend simply needs to generate reports, in which case pure SQL is just fine so long as he knows what he's doing (e.g. avoiding SQL injection issues).
ORM stands for "Object-Relational Mapping". If you don't have the "O" (objects), then it's probably not a good fit for your app. Where ORMs really shine is in persisting objects to the database and loading them from a database.
ORM 代表对象关系映射 - 但看看你的朋友的查询似乎想要一个非常具体的总和表和其他项目...我没有使用过 Ruby 的 Sequel,但我使用过 Hibernate 和 Python 的 SQLAlchemy(用于Django/Turbogears),虽然您可以进行此类查询,但我不认为这是他们的优势。
ORM 的强大之处在于能够找到 Foo->Bar 对象关系,假设您希望 Foo 字段的所有 Bar 对象都大于 X...之类的事情。因此,我不会将 ORM 归类为“好的”解决方案,尽管转向像 Ruby 这样的真正编程语言并通过它而不是 Excel 执行 SQL...这本身就是一个胜利。
只是我的2分钱。
ORM stands for Object Relational Mapping - but looking at the query your friend seems to be wanting a pretty specific table of sums and other items... I've not used Ruby's Sequel, but I've used Hibernate, and Python's SQLAlchemy (for Django/Turbogears) and while you can do these sorts of queries, I don't believe that is their strength.
The power of ORM comes from being able to finding Foo->Bar object relationships, say you want all the Bar objects for Foo's field greater then X... That sort of thing. Therefore I would not classify an ORM as a "good" solution, though moving to a real programming language like Ruby and doing the SQL through it instead of Excel... that in itself is a win.
Just my 2 cents.
在这种情况下,我可能会手动编写它们或使用视图(如果您使用的数据库支持视图)
In a situation like that, I'd probably write them by hand or use a View (if the DB you're using supports views)
当您有对象(业务对象)时,就会使用 ORM。因此,我假设您有一个应用程序,用于创建和管理最终保存到数据库中的业务对象。如果您已经了解了,那么您几乎肯定已经获得了一些关系的表示,并且可能还获得了您将在报告中使用的许多计算。使用 SQL 直接访问数据库以获取报告的问题在于可维护性。
您通常会花费大量精力来确保您的业务对象隐藏其数据库的任何详细信息。您可以在业务对象中实施业务规则并进行常见计算。为团队的所有成员建立一种通用语言等。然后,您使用 ORM 映射到数据库并使用 Habanero< /a> 或 NHibernate 或类似的东西来做到这一点。这一切都很棒。我们以可维护性的名义做这一切,这很棒。您可以迁移您的应用程序、更改您的设计等。
您现在可以编写 SQL 来运行报告,随着时间的推移,您将拥有数百个报告。首先,它们经常重复您在 BusinessObjects 中已有的逻辑(通常没有任何测试),更糟糕的是,Bham Damb 抱歉,可维护性现在已经被塞满了,忘记将该字段从一个表移动到另一个表,忘记将该表拆分为两个,更改该关系等有许多报告会意外中断。
查询域对象/业务对象的问题只是性能问题之一。
总之,如果您正在使用领域驱动设计或业务对象概念,请尝试将它们用于报告。 (出于性能原因,您可能会使用 SQL 或存储过程直接从数据库运行,但请尝试先限制这些使用您的业务对象,然后再使用 SQL)。
当然,另一种选择是使用单独的报告数据库(如某些 BI 概念),因此从事务数据库到报告数据库的映射位于一个位置,并且在您想要更改设计的情况下可以轻松更改。
领域对象(业务对象)和 ORM 拥有所有知识,允许您在使用领域术语时开始构建直接在数据库上运行的高性能查询。让我们希望这些能够继续发展到成为现实。
在此之前,如果您在应用程序中使用业务对象,那么当性能成为 SQL 的一个问题时,请尝试将它们用于报告。
ORM's are used when you have Objects (Business Objects). I am therefore assuming that you have an application with which you creating and Managing the Business Objects that are ultimately saved into the database. If you have then you have almost definitely got some representation of the relationships and probably many of the calculations you are going to use in reports. The problem with using SQL to directly access your database for reports is simply maintainability.
You typically put a lot of effort into ensuring that your Business Objects hide any details of their database. You implement business rules and do common calculations in your Business Objects. Build a common language for all members of the team etc etc. You then use an ORM to map to the database and use Habanero or NHibernate or something like that to do this. This is all great. We do this all in the name of Maintainability and is great. You can migrate your application change your design etc etc.
You now go and write SQL to run reports over time you have hundreds of report. Firstly they often duplicate logic you already have in your BusinessObjects (Usually without any tests) and even worse Bham Damb sorry maintainability is now stuffed forget about moving a that field from one table to another forget about splitting that table into two changing that relationship etc you have a number of reports that are going to break unexpectedly.
The problem with quering through your Domain Objects/Business Objects is simply one of performance.
In summary if you are using Domain Driven Design or Business Object concepts try to use these for reports. (You will probably run directly from DB using SQL or stored procs for performance reasons but try limit these use your Business Objects first and then use SQL).
The other option of course is using a separate reporting database (Like some of the BI concepts) The mapping from your transactional DB to your reporting DB is therefore in one place and easily changeable in cases where you want to change your design.
Domain Objects (Business Objects) and ORMs have all the knowledge to allow you to start building high performing queries that run directly on the Database while using the Domain Terminology. Lets hope that these continue to evolve to a point where this is a reality.
Until then if you are using Business Objects in your application try use them for Reporting when performance is an issue resort to SQL.