ORM的当前状态是什么?

时间:2009-07-02 08:37:37

标签: performance orm

从历史上看,除了最基本的应用之外,我完全反对使用ORMS。

我的理由一直是,它是一个非常漏洞的抽象...主要是因为SQL提供了一种非常强大的方法来从关系源中检索数据,这通常会被ORM搞砸,这样你就会失去很多性能获得没有关系后端的外观。

我一直以为DATA应该始终保存在数据库中,而不是吃掉那些无法扩展的应用程序内存。此外,对通用性能的影响是有害的。例如,如果我需要数据库的所有客户端的名称和地址,SQL在一个查询中为我提供了一种简单的方法来获取它。使用ORM我需要获得所有客户端,然后是每个名称和地址,即使它是懒惰的,它也会花费更多的时间。

这就是我的想法,但上面的任何改变了吗?我看到很多ORMS,比如Entity Framework,NHibernate等。最近他们似乎有很多人气......他们值得吗?他们是否解决了我上面描述的问题?

4 个答案:

答案 0 :(得分:6)

请阅读:All Abstractions Are Failed Abstractions它应该提出很多问题。

性能通常不是ORM的问题 - 如果您确实发现自己处于某种情况,那么通常总是可以选择手工编写ORM使用的SQL语句。

恕我直言,ORM为您提供即时和巨大的开发速度。这就是他们如此受欢迎的原因。正确使用它们并不会让你自己在角落里画画。总是可以选择手动调整性能。

编辑:

即使杰夫专注于Linq to SQL,他所说的关于抽象和性能的同样适用于NHibernate(我从多年的现实应用程序开发中知道)。恕我直言,默认情况下应该使用ORM,因为它们对于臭名昭着的90%的情况来说足够快。读取为ORM编写的代码通常更易于维护和读取,尤其是当您的代码被继承您的代码的下一个开发人员选中时。 Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.永远不要忘记那个人!

此外,他们提供了开箱即用的缓存,延迟加载,工作单元......你的名字。我发现当我对ORM 的表现不满意时,这是我的错误。 ORM会强制您遵守良好的面向对象设计实践,并帮助您塑造域模型。

答案 1 :(得分:1)

在Ruby on Rails方面,ActiveRecord - 本质上是一个ORM--是95%Rails应用程序的基础(虚拟统计,但它就在那里)。实际上,要达到95%,我们可能需要为Rails包含其他ORM,比如DataMapper。

抽象是漏洞,开发人员可以根据需要随时使用SQL。即使您不直接使用SQL,也必须考虑数据库命中数等。例如,在ActiveRecord中,“eager loading”用于避免多个数据库命中,因此您会看到类似这样的内容(包括相关内容)在初始查询中每个帖子的“作者”字段......我认为它在引擎盖下进行连接

for post in Post.find(:all, :include => :author)

关键在于抽象漏洞和所有抽象漏洞一样,但这并不是重点。要决定是否使用抽象,您必须考虑它是否会增加或减少您的一般工作量。换句话说,你会花更多的时间来改进你的概念以使抽象工作,或者它是否准备好做你需要的而不需要太多的黑客攻击(节省你的时间)?

我认为有效的抽象是那些成熟的抽象: ActiveRecord一直存在块(就像Hibernate一样),因此它提供了一种抽象方式修补你通常会担心的大部分泄漏,而不是明确地滚动你自己的低级解决方案(即,不编写SQL)。

除了学习曲线之外,我认为ORM对于大多数数据库访问来说都是一个惊人的节省时间,并且大多数应用程序确实对数据库进行了相当“正常”的使用。虽然它可能不是您的情况,但避免直接数据库访问的ORM通常是早期和不必要的优化的情况。

编辑:我没看过这个,但杰夫的引用是

  

这种抽象是否使我们的代码成为了   最不容易写?至   了解?排除故障?是我们吗   这种抽象比使用更好   我们没有它?

说的基本相同。

答案 2 :(得分:1)

一些更现代的ORM是解决许多现实世界问题的强大工具。好的ORM不会试图隐藏关系模型,但实际上利用它来使OO编程更强大。它们实际上不是抽象,因为它们让你忽略了关系代数的“低级”细节,而是它们是工具包,可以让你在关系模型上构建抽象,并且更容易将数据引入命令模型,跟踪更改并将它们推回数据库。 SQL语言实际上没有提供任何好的方法来将常见谓词分解为可组合的可重用组件,以实现业务级别的抽象。

当然有性能损失,但它主要是一个常数因素,因为你可以使ORM问题出现你自己发布的SQL。就像您的姓名和地址示例一样,在SQLAlchemy中您只需要

for name, address in session.query(Client.name, Client.address):
    # process data

你已经完成了。但是ORM帮助你的地方就是你有可重用的关系和谓词。例如,假设您已经定义了一种方法来加入客户的收藏项目,并使用谓词来查看它是否在销售中。然后,您可以获取具有一些他们喜欢的商品的客户列表,同时还通过以下查询获取指定的销售人员:

potential_sales = (session.query(Client).join(Client.favorite_items)
                  .filter(Item.is_on_sale)
                  .options(eagerload(Client.assigned_salesperson)))

根据我的意见,查询的目的是编写更快,更清晰,更容易理解,而不是十几行SQL。

答案 3 :(得分:0)

对于任何抽象,你必须以表现或泄露的方式支付。我同意你反对ORM,因为SQL是一种干净优雅的语言。我有点编写自己的小框架,为我做这些事情,但是嘿,然后我用自己的ORM坐在那里(但是对它的控制比Hibernate更多)。 Hibernate背后的人说它很快。它应该能够对你的数据库进行大约95%的枯燥工作(简单的查询,更新等等)。但是如果你愿意,你可以自由地完成最后5%的工作(你可以在特殊情况下自己编写自己的映射) )。

我认为大多数受欢迎程度源于许多程序员都很懒惰,并希望建立框架来为他们做肮脏无聊的持久性工作(我可以理解),但抽象的价格总会存在。在选择在严肃项目中使用ORM之前,我会仔细考虑我的选择。