ORM与传统的数据库查询,这是他们的领域?

时间:2010-07-29 07:30:51

标签: database

ORM似乎是一个快速增长的模式,在他们身边都有利弊。来自Richard Kiessig的超快ASP.NET(http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839/ref=pd_bxgy_b_text_b):

“我喜欢他们,因为他们允许我非常快速地开发小型的概念验证网站。我可以将我需要的大部分SQL和相关复杂性放在一边,并专注于对象,业务逻辑和演示但是,与此同时,我也不关心它们,因为不幸的是,它们的性能和可扩展性通常很差,即使它们与一个全面的缓存系统集成(当你意识到这一点时,它的原因就变得清晰了)如果配置正确,SQL Server本身实际上只是一个大数据缓存“

我的问题是:

  • 您对理查德的想法有何评论?你同意他的意见吗?如果没有,请说明原因。

  • ORM和传统数据库查询的最佳字段是什么?换句话说,你应该在哪里使用ORM,你应该使用传统的数据库查询:),哪种类型/大小的应用程序你无疑应该选择ORM /传统的数据库查询

提前致谢

9 个答案:

答案 0 :(得分:30)

我不能同意对ORM表现不好的共同抱怨。到目前为止,我已经看过很多普通的SQL应用程序。虽然理论上可以编写优化的SQL,但实际上,它们通过编写未优化的业务逻辑来破坏所有的性能提升。

使用纯SQL时,业务逻辑高度耦合到db模型和数据库操作,并且优化取决于业务逻辑。因为没有oo模型,所以无法传递整个对象结构。我已经看到许多应用程序传递主键并一次又一次地从每个层上的数据库中检索数据。我见过在循环中访问数据库的应用程序。等等。问题是:因为业务逻辑已经难以维护,所以没有空间可以进行更多优化。通常,当您尝试重用至少一些代码时,您会认为它并未针对每种情况进行优化。性能因设计而变差。

ORM通常不要求业务逻辑过多关注数据访问。在ORM中实现了一些优化。有缓存和批次的能力。这种自动(和运行时动态)优化并不完美,但它们将业务逻辑与其分离。例如,如果有条件地使用了一段数据,它会根据请求使用延迟加载(恰好一次)加载它。你不需要做任何事情就可以做到这一点。

另一方面,ORM的学习曲线陡峭。我不会将ORM用于简单的应用程序,除非ORM已被同一团队使用。

ORM的另一个缺点是(实际上不是ORM本身,而是你将使用关系数据库和对象模型),团队需要在两个世界中都很强大,关系也是如此作为oo。

结论:

  • ORM对于以业务逻辑为中心的应用程序非常强大,其数据结构足够复杂,具有OO模型将具有优势。
  • ORM通常具有(某种程度上)陡峭的学习曲线。对于小型应用程序,它可能会变得太昂贵。
  • 基于简单数据结构的应用程序,没有太多的逻辑来管理它,很可能更容易和直接用简单的SQL编写。
  • 拥有高水平数据库知识并且没有太多oo技术经验的团队通过使用普通的sql更有效率。 (当然,根据他们编写的应用程序,建议团队切换焦点)
  • 使用ORM,具有高水平知识和唯一基本数据库经验的团队可能更有效率。 (同样在这里,根据他们编写的应用程序,建议团队切换焦点)

答案 1 :(得分:7)

ORM很老了,至少在Java世界里。 ORM的主要问题:

  • 面向对象的模型和关系模型是完全不同的。
  • SQL是一种基于关系代数访问数据的高级语言,不同于任何OO语言,如C#,Java或Visual Basic.Net。混合这些可以是两个世界中最糟糕的,而不是最好的

有关更多信息,请在网上搜索“对象 - 关系阻抗不匹配”

等内容

无论哪种情况,一个好的ORM框架都会为您节省相当多的样板代码。但是你仍然需要知道SQL,如何设置一个好的SQL数据库模型。首先使用SQL创建一个好的数据库模型,然后根据它建立一个OO模型(不是相反)

但是,如果您确实需要使用SQL数据库,则上述内容仅适用。我也建议调查NoSQL运动。像Cassandra,Couch-db这样的东西。谷歌搜索.net解决方案时,我发现了这个stackoverflow问题:https://stackoverflow.com/questions/1777103/what-nosql-solutions-are-out-there-for-net

答案 2 :(得分:4)

我是该书的作者,并在问题中引用了该文字。

让我强调补充一点,我反对使用业务对象或面向对象的编程。

我对传统ORM的一个问题 - 例如,LINQ to SQL或实体框架 - 是因为它甚至导致开发人员在他们甚至没有意识到他们正在这样做时进行数据库调用。反过来,这又是一个性能和可​​伸缩性的杀手。

我查看了许多网站的性能问题,并发现数据库混乱是导致严重问题的最常见原因之一。不幸的是,ORM倾向于在黑桃中鼓励骚扰。

我对ORM的其他抱怨包括:

  • 不支持命令批处理
  • 不支持多个结果集
  • 不支持表值参数
  • 不支持本机异步调用(从后台线程调用它们不计算在内)
  • 支持SqlDependency和SqlCacheDependency,如果/什么时候可以使用,那就很糟糕了

我不反对在战术上使用ORM来解决具体的业务问题。但我确实反对随意使用它,开发人员在同一页面上做几十次完全相同的数据库调用,或者在不考虑缓存和更改通知的情况下发出非常昂贵的查询,或者在可伸缩性时完全忽略异步操作是一个问题。

答案 3 :(得分:2)

我相信这个站点使用Linq-to-SQL,并且它“相当”高流量......我认为从编写样板代码到访问/插入/更新简单项目所节省的时间是非常宝贵的,但那里如果你有更复杂的东西,你可以选择下拉到调用SPROC,你知道你可以直接写一些尖叫的快速SQL。

我不认为这些事情必须互相排斥 - 利用两者的优点,如果您的应用程序的某些部分开始变慢,那么您可以根据需要进行优化。

答案 4 :(得分:2)

ORM比Java和.NET都要老。我所知道的第一个是TopLink for Smalltalk。这是一个像持久对象一样古老的想法。

每个“网络上的CRUD”框架,如Ruby on Rails,Grails,Django等,都使用ORM来实现持久性,因为它们都假设你是从一个干净的工作表对象模型开始的:没有遗留模式可以打扰。您可以从对象开始为问题建模并从中生成持久性。

它通常与遗留系统相反:模式是长寿的,您可能有也可能没有对象。

令人惊讶的是,您可以通过“网络上的CRUD”框架快速启动和运行原型,但我不认为它们被用于在大公司中开发企业应用程序。也许这是财富500强的偏见。

我知道的数据库管理员告诉我他们不喜欢ORM生成的SQL,因为它通常效率低下。他们都希望有办法手工调整它。

答案 5 :(得分:1)

我同意这里已经提出的大多数观点。

ORM在.NET中并不陌生,LLBLGen已经存在了很长时间,我已经在.NET中使用它们已经有5年了。

我看到在没有ORM的情况下编写的代码非常糟糕(无效的SQL查询,错误的索引,嵌套的数据库调用 - 哎哟!)和用ORM编写的错误代码 - 我确信我已经为某些代码做出了贡献也是错误的代码:)

我要补充的是,ORM通常是一个功能强大且提高生产力的工具,它允许您不再担心大多数应用程序的管道数据库代码,并专注于应用程序本身。当您开始尝试编写复杂的代码(例如报告页面或复杂的UI)时,您需要了解底层发生的事情 - 无知可能非常昂贵。但是,使用得当,它们非常强大,IMO不会对您的应用程序性能产生不利影响。我对一个没有使用ORM的项目感到高兴。

答案 6 :(得分:0)

编程是关于编写用于商业用途的软件。我们越是专注于业务逻辑和演示,而不是那些仅在某些时间点(当软件出现故障,软件需要升级等时)的技术问题时,就越好。

最近我读到了来自here的Reddit创始人关于可扩展性的讨论,以及引起我注意的他的一行:

  

“必须处理复杂问题   关系数据库(关系,   连接,约束)是一个问题   过去“。

从我看过的情况来看,维护一个复杂的数据库模式,当涉及可伸缩性时,随着网站的增长而变得非常痛苦(你添加一个字段,重新分配约束,重新映射外键......等等)。我不清楚为什么会这样。他们没有使用NOSQL数据库,他们在Postgres。

除此之外,还有ORM,另一层抽象。它简化了代码编写,但几乎经常会降低性能。对我来说,一个简单的数据库抽象库就可以了,就像那里的轻量级AR库以及特定于数据库的“纯文本”查询一样。我无法向您展示任何基准,但我已经看到了ORM,他们中的大多数人都说“ORM通常很慢”。

理查德涵盖了硬币的两面,所以我同意他的观点。

至于字段,我真的不太了解你所询问的“字段”的上下文。

答案 7 :(得分:0)

正如其他人所说,你可以写出表现不佳的ORM代码,你也可以编写表现不佳的SQL。

使用ORM并不能免除您了解SQL,并了解查询如何组合在一起。如果可以优化SQL查询,通常可以优化ORM查询。例如,通过hibernate的条件和HQL查询,您可以控制连接哪些关联以提高性能并避免使用其他select语句。了解如何创建索引以改进最常见的查询可能会影响您的应用程序性能。

ORM购买的是统一,可维护的数据库访问。它们提供了额外的验证层,以确保您的OO代码尽可能与数据库访问匹配,并防止您编写某些类别的愚蠢错误,例如编写易受SQL注入攻击的代码。当然,您可以参数化自己的查询,但ORM可以在不考虑的情况下为您提供优势。

答案 8 :(得分:0)

从来没有得到任何东西,除了ORM包的痛苦和沮丧。如果我按照他们自动生成的方式编写我的SQL - 是的,我声称速度快,而我的代码会很慢:-)你见过ORM生成的SQL吗?只有PK-s,只使用FK-s对“继承”的误导性解释,如果它想要进行分页,它会将整个记录集转储给你,然后丢弃90%:-)))然后它锁定了所有内容因为它必须接受大量记录,比如它回到了50年前的IBM批量处理。

有一段时间我认为ORM的最大问题是分裂(不会有50年的标准 - 每年不同的API,原谅“模型”:-)和意识形态化(每个人都向你推销一个大哲学 - 总是当然比其他人更好:-)然后我意识到,真正的业余主义是混乱的根本原因,其他一切只是后果。

然后这一切开始变得有意义了。 ORM从未打算保持高效或可靠 - 甚至不在名单上:-)这是学术性的,从第一天开始的“概念”玩具,教授的安慰奖激发了他们所有的“关系”研究论文当IBM和甲骨文开始销售那种糟糕的SQL产品并赚钱时,Prolog开始流失: - )

我最信任的一个是LINQ,但这只是因为它可以很容易地完成所有“跟踪”并且使用就像普通SQL代码的反序列化层一样。然后我读到了管理连接的对象如何产生自发的故障,听起来像过早的GC,而它仍然有一些悬挂的东西。在那之后我不可能冒着风险 - 不,不是我的头: - )

所以,让我列一个清单:

  • 完全邋code的代码 - 不会遭受错误和糟糕的性能
    • 不会从ORM的10-100倍“交易”中获取死锁
  • 功能大幅减少 - SQL现在具有巨大的表现力
  • 将你绑定到边缘和草率的API(每个ORM旨在劫持你的代码库)
    • SQL查询具有高度可移植性,SQL知识完全可移植
  • 我仍然需要知道SQL只是为了清理ORM的混乱
  • 对于“概念验证”,我可以序列化为二进制或XML文件
    • 速度不是很慢,零错误库和一个XPath无论如何都可以选择更好
    • 我实际上已经从XML文件中完成了繁忙的交通网站
    • 如果我真的需要真正的图表,那么我对DB没有用 - 没什么可查询的
    • 我可以将blob序列化并以3行代码
    • 转储到SQL中
  • 如果有人声称他从数据库到用户界面都做了这一切 - 请保持代码库锁定:-)
    • 并备份你的工资单数据库 - 你会感谢我后者: - )))
  • NoSQL基础比ORM更诚实 - “我们专注于持久性”
    • 并且具有更好的代码质量 - 并不感到惊讶

这将是短名单:-)顺便说一句,现代SQL引擎现在做树和空间索引,更不用说没有单一记录的分页浪费了。 ORM-s实际上是“解决”10年前的问题并促进业余爱好。到那个程度NoSQL,也称为文件