ORM的当前状态是什么?

时间:2022-09-23 04:07:53

Historically I've been completely against using ORMS for all but the most basics applications.

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

My reasoning has and always has been that it's a very leaky abstraction ... mostly because SQL provides a very powerful way to retreive data from a relational source which usually gets messed up by the ORM so that you lost a lot of performance to gain an appearance of not having a relational backend.

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

I've always thought the DATA should always be kept in the Data Base, not eat up application memory which won't scale anyway. In addition the performance hit of being to generic is harmful. For example, if I need the name and address of all the clients of my database SQL provides me with an easy way to get it, in one query. With an ORM I need to get all the clients and then each name and address, even if it's lazy loaded it's gonna take a LOT longer.

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

That's what I think but has any of the above changed? I'm seeing a lot of ORMS like the Entity Framework, NHibernate, etc. And they seem to have a lot of popularity lately... Are they worth it? Do they solve the problems I describe above??

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

4 个解决方案

#1


Please read: All Abstractions Are Failed Abstractions It should put a lot of your questions in perspective.

请阅读:所有抽象都是失败的抽象它应该提出很多你的问题。

Performance is usually not an issue with ORM - and if you really find yourself in a situation where it is, then there usually is always the option to handcraft the SQL statements the ORM uses.

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

IMHO ORM give you an instant and huge development speed increase. That's why they are so popular. And using them right does not make you paint yourself in a corner. There is always the option of hand tuning the performance.

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

Edit:

Even though Jeff focuses on Linq to SQL all he says about abstractions and performance are equally true for NHibernate (which I know from years of real world app development). IMHO one should use by default an ORM since they are more than fast enough for the notorious 90% of situations. Reading code written for an ORM usually is more maintainable and readable especially when your code is picked up by the next developer that inherits your code. Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. Never forget about that guy!

尽管Jeff专注于Linq to SQL,但他所说的抽象和性能对于NHibernate来说同样如此(我从多年的真实应用程序开发中知道)。恕我直言,默认情况下应该使用ORM,因为它们对于臭名昭着的90%的情况来说足够快。读取为ORM编写的代码通常更易于维护和读取,尤其是当您的代码被继承您的代码的下一个开发人员选中时。总是编码好像最终维护你的代码的人是一个知道你住在哪里的暴力精神病患者。别忘了那家伙!

In addition they give out of the box caching, lazy loading, unit of work, ... you name it. And I found that when I was not happy about the performance of the ORM it was MY fault. ORM do force you to adhere to good OO design practices and help you shape your Domain Model.

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

#2


On the Ruby on Rails side, ActiveRecord -- essentially an ORM -- is the basis of 95% of Rails applications (made-up statistic, but it's around there). Actually, to get to that 95% we would probably need to include other ORMs for Rails, like DataMapper.

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

The abstraction is leaky, and a developer can always dip down to SQL as necessary. Even when you're not using SQL directly, you have to think about number of database hits, etc. For instance, in ActiveRecord, "eager loading" is used to avoid multiple database hits, so you see stuff like this (includes the related "author" field of each Post in the initial query... it does a join under the hood, I think)

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

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

The point is that the abstraction leaks as do all abstractions, but that's not really the point. To decide whether to use the abstraction or not, you have to consider whether it will add to or reduce your general workload. In other words, will you spend more time retrofitting your concepts to make the abstraction work, or is it ready to do what you need without much hacking (saving you time)?

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

I think that the abstractions that work are those that are mature: ActiveRecord has been around the block a ton (as has Hibernate), so it provides an abstract way to patch most of the leaks you would normally be worried about, without explicitly rolling your own lower-level solution (i.e., without writing SQL).

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

Beyond the learning curve, I think that ORMs are an amazing time-saver for most of your database access, and that most apps actually do make quite "normal" use of the DB. While it may not be your case whatsoever, eschewing an ORM for direct DB access is often a case of early, and unnecessary, optimization.

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

Edit: I hadn't seen this, but the Jeff quote is

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

Does this abstraction make our code at least a little easier to write? To understand? To troubleshoot? Are we better off with this abstraction than we were without it?

这种抽象是否使我们的代码至少更容易编写?要明白吗?排除故障?这种抽象比我们没有它更好吗?

saying essentially the same thing.

说的基本上是一样的。

#3


Some of the more modern ORM's are really powerful tools that solve a lot of real world problems. The good ORM's don't try to hide the relational model from you, but actually leverage it to make OO programming more powerful. They really aren't abstractions in the sense that they let you ignore the "lowlevel" details of relational algebra, instead they are toolkits that let you build abstractions on the relational model and make it easier to bring in data into the imperative model, track the changes and push them back to the database. The SQL language really doesn't provide any good way to factor out common predicates into composable, reusable components to achieve businesstule level abstractions.

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

Sure there is a performance hit, but it's mostly a constant factor thing as you can make the ORM issue what ever SQL you would issue yourself. Like for your name and address example, in SQLAlchemy you'd just do

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

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

and you're done. But where the ORM helps you is when you have reusable relations and predicates. For instance, say you have defined a way to join to a client's favorited items, and a predicate to see if it is on sale. Then you can get the list of clients that have some of their favorite items on sale while also fetching the assigned salesperson with the following query:

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

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

Atleast for me, the intent of the query is a lot faster to write, clearer and easier to understand when written like this, instead of a dozen lines of SQL.

至少对我而言,查询的目的是编写更快,更清晰,更容易理解这样写,而不是十几行SQL。

#4


As to any abstraction, you'll have to pay either in form of performance, or leaking. I agree with you in being against ORM's, since SQL is a clean and elegant language. I've sort of written my own little frameworks which do this things for me, but hey, then I sat there with my own ORM (but with a little more control over it than for example Hibernate). The people behind Hibernate states that it is fast. It should be able to do about 95% of the boring work against your database (simple queries, updates etc..) but gives you freedom to do the last 5% yourself if you want (you could always write your own mappings in special cases).

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

I think most of the popularity stems from that many programmers are lazy and want established frameworks to do the dirty boring persistence job for them (I can understand that), but the price of an abstraction will always be there. I would consider my options thoroughly before choosing to use an ORM in a serious project.

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

#1


Please read: All Abstractions Are Failed Abstractions It should put a lot of your questions in perspective.

请阅读:所有抽象都是失败的抽象它应该提出很多你的问题。

Performance is usually not an issue with ORM - and if you really find yourself in a situation where it is, then there usually is always the option to handcraft the SQL statements the ORM uses.

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

IMHO ORM give you an instant and huge development speed increase. That's why they are so popular. And using them right does not make you paint yourself in a corner. There is always the option of hand tuning the performance.

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

Edit:

Even though Jeff focuses on Linq to SQL all he says about abstractions and performance are equally true for NHibernate (which I know from years of real world app development). IMHO one should use by default an ORM since they are more than fast enough for the notorious 90% of situations. Reading code written for an ORM usually is more maintainable and readable especially when your code is picked up by the next developer that inherits your code. Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. Never forget about that guy!

尽管Jeff专注于Linq to SQL,但他所说的抽象和性能对于NHibernate来说同样如此(我从多年的真实应用程序开发中知道)。恕我直言,默认情况下应该使用ORM,因为它们对于臭名昭着的90%的情况来说足够快。读取为ORM编写的代码通常更易于维护和读取,尤其是当您的代码被继承您的代码的下一个开发人员选中时。总是编码好像最终维护你的代码的人是一个知道你住在哪里的暴力精神病患者。别忘了那家伙!

In addition they give out of the box caching, lazy loading, unit of work, ... you name it. And I found that when I was not happy about the performance of the ORM it was MY fault. ORM do force you to adhere to good OO design practices and help you shape your Domain Model.

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

#2


On the Ruby on Rails side, ActiveRecord -- essentially an ORM -- is the basis of 95% of Rails applications (made-up statistic, but it's around there). Actually, to get to that 95% we would probably need to include other ORMs for Rails, like DataMapper.

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

The abstraction is leaky, and a developer can always dip down to SQL as necessary. Even when you're not using SQL directly, you have to think about number of database hits, etc. For instance, in ActiveRecord, "eager loading" is used to avoid multiple database hits, so you see stuff like this (includes the related "author" field of each Post in the initial query... it does a join under the hood, I think)

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

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

The point is that the abstraction leaks as do all abstractions, but that's not really the point. To decide whether to use the abstraction or not, you have to consider whether it will add to or reduce your general workload. In other words, will you spend more time retrofitting your concepts to make the abstraction work, or is it ready to do what you need without much hacking (saving you time)?

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

I think that the abstractions that work are those that are mature: ActiveRecord has been around the block a ton (as has Hibernate), so it provides an abstract way to patch most of the leaks you would normally be worried about, without explicitly rolling your own lower-level solution (i.e., without writing SQL).

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

Beyond the learning curve, I think that ORMs are an amazing time-saver for most of your database access, and that most apps actually do make quite "normal" use of the DB. While it may not be your case whatsoever, eschewing an ORM for direct DB access is often a case of early, and unnecessary, optimization.

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

Edit: I hadn't seen this, but the Jeff quote is

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

Does this abstraction make our code at least a little easier to write? To understand? To troubleshoot? Are we better off with this abstraction than we were without it?

这种抽象是否使我们的代码至少更容易编写?要明白吗?排除故障?这种抽象比我们没有它更好吗?

saying essentially the same thing.

说的基本上是一样的。

#3


Some of the more modern ORM's are really powerful tools that solve a lot of real world problems. The good ORM's don't try to hide the relational model from you, but actually leverage it to make OO programming more powerful. They really aren't abstractions in the sense that they let you ignore the "lowlevel" details of relational algebra, instead they are toolkits that let you build abstractions on the relational model and make it easier to bring in data into the imperative model, track the changes and push them back to the database. The SQL language really doesn't provide any good way to factor out common predicates into composable, reusable components to achieve businesstule level abstractions.

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

Sure there is a performance hit, but it's mostly a constant factor thing as you can make the ORM issue what ever SQL you would issue yourself. Like for your name and address example, in SQLAlchemy you'd just do

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

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

and you're done. But where the ORM helps you is when you have reusable relations and predicates. For instance, say you have defined a way to join to a client's favorited items, and a predicate to see if it is on sale. Then you can get the list of clients that have some of their favorite items on sale while also fetching the assigned salesperson with the following query:

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

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

Atleast for me, the intent of the query is a lot faster to write, clearer and easier to understand when written like this, instead of a dozen lines of SQL.

至少对我而言,查询的目的是编写更快,更清晰,更容易理解这样写,而不是十几行SQL。

#4


As to any abstraction, you'll have to pay either in form of performance, or leaking. I agree with you in being against ORM's, since SQL is a clean and elegant language. I've sort of written my own little frameworks which do this things for me, but hey, then I sat there with my own ORM (but with a little more control over it than for example Hibernate). The people behind Hibernate states that it is fast. It should be able to do about 95% of the boring work against your database (simple queries, updates etc..) but gives you freedom to do the last 5% yourself if you want (you could always write your own mappings in special cases).

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

I think most of the popularity stems from that many programmers are lazy and want established frameworks to do the dirty boring persistence job for them (I can understand that), but the price of an abstraction will always be there. I would consider my options thoroughly before choosing to use an ORM in a serious project.

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