ORM使用数据库抽象有什么好处?[关闭]


19

我开始使用我选择的框架推荐的ORM,尽管我喜欢ORM提供的附加抽象层的想法,但我开始意识到这实际上意味着什么。这意味着我不再使用数据库(mysql),并且所有特定于mysql的功能都消失了,就像它们不存在一样。

ORM的想法是,它试图通过使所有数据库不可知来帮助我。这听起来不错,但是通常我选择特定的数据库系统是有原因的。但是通过走数据库不可知路线,ORM会采用最低的公分母,这意味着我最终会获得最小的功能集(所有数据库都支持这些功能)。

如果我知道从长远来看不会切换基础数据库怎么办?为什么还不访问特定于数据库的功能?


2
+1:非常有趣。我通常是ORM的拥护者,但我通常认为RDBMS等同(我最近开始认为这是错误的)。
史蒂文·埃弗斯

听起来您只是想确认自己的观点;博客可能比问答网站更适合您。

您可能不需要的只是ORM提供的内容。您只想将对象数据存储在数据库中,这就是ORM要做的。您不需要任何其他“功能”。
CJ7

Answers:


14

我以相同的方式看待它。任何不允许您在必要时进入其基础的抽象都是邪恶的,因为它会导致代码中出现各种丑陋的抽象反转。

在工作中,我们有一个运行良好的本地ORM,但是在某些时候,当我们需要某些其功能未明确提供的内容时,有一种方法可以将字符串直接放入生成的查询中,从而允许必要时使用原始SQL。

IMO任何不具有此功能的ORM都不值得从中进行编译。


drops it directly into the query it's generating听起来不错。您知道您编写此本地ORM花了多长时间吗?我想在其中的一个开源ORM中看到类似的内容。
jblue 2010年

+1。我要抽象并失去与之连接的最后一件事是处理应用程序(数据)中最重要的方面。
Fosco 2010年

1
我喜欢能够在必要时潜入水下,只要该潜入涉及越过隐喻的围栏即可:“这里是巨龙。注意您的脚步。”
Frank Shearar 2010年

1
@Jblue:不知道。都是几年前写的,很久才被我录用。他们在任何人使用术语之前就建立了ORM。在我们的代码库中,通常只将其称为“对象模型”。
梅森惠勒

3
我同意。对于基本和常用的东西,ORM很有帮助。但是有时候您需要更深入一些,如果ORM没有提供这种功能,那么这将是您遇到的另一个问题。
Nikos Steiakakis

14

ORM的公分母最低

我必须不同意你的说法。我将以nHibernate为例。与大多数ORM一样,此框架支持许多数据库,包括最受欢迎的数据库,而不论版本(和受支持的功能)如何。

快速说明:您仅提及数据库抽象。那是许多好处之一,但是我真的认为面向对象的功能更强大(例如:继承)。还有You design your domain model first...

...回到抽象。它不是最低的公分母。在nHibernate中,您有方言。它允许您使用相同的代码来查询不同的数据库。方言为您提供功能管理。正确的说法是a given dialect will try to use all the power of a given database system

SqlServer2005方言为例,该方言在引入时就是利用了新的SQL Server 2005分页功能。使用该方言而不是SqlServer2000仅仅提高您的演奏。

当然也有例外,但是在使用nHibernate的很多年中,我没有遇到过一个,而且我的应用程序非常以数据为中心。


+1代表NHibernate。与其他ORM相比,学习曲线有些许困难,但是付出的努力是值得的。
richeym 2010年

1
我想听听一些DBA的意见。在我的上一份工作中,Hibernate只是麻烦而已(它生成的SQL绝对令人作呕。)
Fosco 2010年

对此评论+1。现场。当您开始比较像nHibernate(具有缓存,延迟加载等)之类的优质ORM的功能时,您会发现为什么这种抽象是好的,而特定于数据库的需求却不那么重要。
克里斯·霍尔姆斯

1
Fosco,给nHibernate另一个机会。像任何其他技术一样,您必须了解内部发生了什么,才能正确使用它。

+ 1,ORM是Java可以做的与特定JDBC驱动程序可以做的最大的交集。您可以自由选择要在应用程序的持久层中进行的投资数量
bobah 2010年

5

这个想法很简洁,但是我从来没有动过使用ORM工具的意义。我自己编写SQL(或处理使用的任何存储)对我来说不是问题。但是,我确实可以从事数量较少,产品寿命更长的项目,因此一旦有了手动编码的SQL和DB操作,就可以使用它。此外,您显然可以处理所需的任何直接SQL查询,而不必使您的流程适应ORM工具的思维方式。

因此,我想问题应该在您跳入其中一个之前:

实际上从使用它们中学到了什么吗?也就是说,您是否通过实施ORM工具节省了足够的精力以使其值得使用,并使其值得为系统增加额外的复杂性?(对于商业应用程序尤其如此,其中额外的“部分”现在成为解决潜在支持问题的额外载体)

然后,额外的抽象层会对应用程序产生负面影响吗?它会比手工编码的SQL等慢吗?


5

O / RM经常受到批评。几年前,Ted Neward将其称为“ 计算机科学的越南 ”。O / RM

起步良好,随着时间的流逝而变得更加复杂,并且不久之后就将其用户陷于一个没有明确分界点,没有明确获胜条件,也没有明确退出策略的承诺中。

除非您自己编写临时映射(在许多情况下,这是一个不错的解决方案,正如其他人已经说过的那样),否则您可以考虑使用非关系数据库之类的替代方法。有人说真正的对象数据库更好,在这种情况下提到的其他流行词是LINQ,Ruby和TutorialD。我想,与真正的关系数据库相比,存在真正的对象数据库。但是在实践中,我发现概念数据建模(即找出要存储数据的实际对象以及这些对象之间的相互关系)比摆弄如何在任何情况下表达概念模型更重要。编程或数据库语言。


2
很棒的阅读。我的职业生涯已全面发展,并重新拥抱了关系模型,并取得了圆满成功。
JE队列

2
+1 @Xepoch-我最近有一个关于face re:ORM的信息-为什么SQL被冷落?当然可以抽象-但是ORM似乎会引起SQL恐惧症。
2011年

1
@sunwukung,我并不总是同意,但是我现在确实认为应该将SQL视为第一级逻辑层,而不仅仅是作为有线协议使用的逻辑层。
JE队列

3

有什么选择?

这是一个有趣的概念。通过抽象化基础数据库的功能,我们肯定会丢失特定数据库实现的某些功能。(是否应该依赖于特定的数据库功能是另一个论点)我想这可以通过特定于数据库的ORM来解决,该ORM允许您访问特定的功能,但这可能比它的价值更大,而且步履维艰。方向错误。

在一天结束时,您必须问自己- 替代方法是什么?

我们是否应该停止使用ORM,然后自己重​​新编写所有数据库访问权限?当然,我们可能无法通过ORM访问某些数据库功能,但是您始终可以使用传统技术来访问这些功能。最后,您在生产率方面获得的收益完全超过了弊端。


我会质疑是否需要使用理性的数据库。令我困扰的是,即使他们不是正确的解决方案,人们也会立即转向RDBMS。例如,对象数据库为许多问题提供了非常优雅的解决方案。他们完美吗?不,但是人们很少去评估它们。有一个令人不安的趋势:“我需要存储数据,我将使用SQL!”
Matt Olenik 2010年

6
@Matt:RDBMSes是经过实践检验和证明的,易于理解的技术。有大量具有丰富经验的人,以及大量的第三方工具。从企业的角度来看,当您处理诸如数据之类非常有价值的东西时,它具有很多价值。在较小的项目中,能够启动一个项目(如LAMP Web服务)并保留大部分软件并对其进行详细记录仍然具有价值。
David Thornley 2010年

3

ORM基本上等于“未存储过程 ”。在那里,我创造了一个学期。

ORM所做的一切,您都可以使用视图,触发器和存储过程进行复制。它们有助于将原始SQL抽象化,并使标准化数据库保持一致。但这仅适用于简单情况。如果处理的马赫数据太多,则可能会浪费性能。(PHP中的ORM通常会在数据脚本方面使用,因为SQL构建器链无法抽象所有内容。)

但是像往常一样,这一切都取决于手头的应用程序和任务。


2
“未存储的过程”-正确的术语是“参数化SQL”。您只是在
摸索

@richeym:PHP中的大多数ORM都不使用准备好的语句,也不使用参数化的占位符。一直都是SQL转义和连接。确保它们比繁琐的手动SQL查询提供更高级别的优势。然而,从逻辑上讲,它们将处理逻辑从数据库中删除,因此从“未存储的过程”中删除。
mario 2010年

3

使用ORM的一件事是,许多粉丝倾向于声称我们不再需要了解SQL和RDB理论。结果从滑稽到完全灾难性不等。尽管ORM制造和专家指出进行数百万次的测试,但我们必须非常了解 SQL和RDB理论才能正确使用和配置ORM。

人们为什么将在许多但不是所有情况下都可以使用的工具变成神奇的,普遍适用的银弹,这超出了我的理解。


1

去年,我开发了一个内部应用程序,该应用程序经常更改,我很高兴我们使用了ORM。该应用程序是变更管理团队的支持应用程序,随着大型项目的发展,我们的小应用程序对不存在且几个月前无法预见的情况提出了新要求。

感谢ORM(PHP中的Propel),我们拆分了一些代码逻辑,因此一个函数添加了查询的“记录有效”部分,另一个添加了安全性(“仅当用户使用时显示这些记录具有这些功能”),...如果基础结构发生了变化(“记录有效性”应考虑一个额外的字段),我们只需更改一个函数,而不更改二十个SQL子句。

我们来自所有(很好,大多数)SQL子句都存储在单独的XML文件中的情况,因此“数据库更改将易于处理”。相信我,他们不是。其中一个部分太可怕了,我不得不将其提交给《每日WTF》

如果查询太复杂而无法用Propel Criteria来表达,或者我们需要一些特定于供应商的功能(由于使用的是MySQL,因此大多是全文搜索),那么Propel就没有问题。您可以添加自定义条件,或者在真正需要时使用原始SQL(现在更容易与实际的Propel对象结合使用)。您可以轻松地将特定于供应商的加载项添加到生成的类中,因此您可以兼得两全:应用程序代码中没有SQL,但是具有数据库引擎的所有功能。


1

但关键是您可以远离数据库进行编程,这意味着您无需像在数据库中一样思考。

我现在在C#中工作,并且大量使用LINQ,因此有很多流畅的方法。我不需要考虑对象的存储或查找方式,甚至不必在程序级进行保存,而在业务层级则很少考虑。

特定数据库本身提供的方法经常在DB连接器中使用,因此您无需了解这些优化即可获得这些优化。

您仍然可以在DB端编写函数。通常,您只需将它们映射即可。

最重要的是,这样的分离允许可测试性,并迫使您(稍微)编写更好的结构化代码


2
同样,为什么需要远离数据库编程?为什么不选择将数据库作为开发中不可或缺的一部分呢?如果您不需要RDBMS,为什么要在它上面放一个ORM?
JE队列

1
这是不可或缺的一部分。数据库在维护和执行关系以及检索原始数据方面做得很好。但是,您想使用此数据执行的操作很可能已经在ORM包装器中进行了处理。除了关键的事情,为什么还要将逻辑从业务层中剔除?
burnt_hand

@burnt_hand- “但是关键是您可以远离数据库编程,这意味着您不必像在数据库中那样思考。” 有哪些普遍优势?当您的应用只是在寻找一种持久化对象的方法时,我可以将其视为一种优势。但是对于关系数据,OLTP等而言,远离数据库进行编程是浪费大量时间的一种方法。
luis.espinal

@ luis.espinal-什么意思使自己忙得不可开交?我真的很好奇。你有例子吗?
burnt_hand

@burnt_hand-实际上我确实有几个真实的例子。最近的一个涉及非常大的域模型,并且出于性能的考虑,项目必须在启动时上载所有休眠映射。最终的会话工厂最终会消耗多达30%的已用内存...仅用于绑定。现在,使用ORM提交的代码太过繁琐,无法重写。现在这具有实际意义,因为该应用程序接近其应运行的硬件的物理限制。笨蛋
luis.espinal,2010年

1

ORM 还可以让您访问特定于数据库的功能,这取决于您所使用的ORM以及它提供的功能。

例如,在我当前正在研究的项目中,我们正在使用Java Persistence API和Hibernate。即便如此,我们仍使用了一些特定于数据库的功能,例如使用soundex在表中进行搜索。

对我来说,使用ORM的主要好处不一定是它使应用程序数据库不可知(尽管这也是一件好事),但是我在大多数情况下不必考虑如何存储和存储事物。检索。

但是,在某个时候,您很可能必须考虑这一点,具体取决于应用程序的要求。ORM不是魔术。


1

我写了自己的文章,这有助于我更轻松地进行选择和插入。

Evey db特定的东西可用。我只需要自己编写查询,库就可以为我提供帮助(我可以使用'?'和params而不是手动命名参数并使用.Add)

我猜我的一半吸一半有用。我在ORM世界中获得了一些帮助,并且在查询世界中发挥了重要作用。


1

编写代码以插入和选择,内联或使用存储的proc更新并通过DAL将它们映射回更长的时间,这只是在特殊情况下才有用。可用的ORM,支持的数据库和语言,您应该问的问题是为什么不使用ORM?

它们是标准化的,通用的,指定的或通用的。此外,它更快,更容易实现。我已经使用了subsonic,linq-to-sql和实体框架。它使开发人员可以专注于逻辑和业务规则,而不是数据库映射。


1
使用或不使用ORM的原因很多。ORM不是万能药,实际上很少有人知道如何有效地使用它们。此外,在许多情况下,业务逻辑已经以非常自然的方式(部分地)反映在RDBMS中已经存在的关系中(这是我过去和现在遇到的最常见的情况)。精心设计的RDBM具有强大,易于理解,久经考验的数学基础。当然,并非所有内容都应使用RDMB建模,但是同样地,ORM也不是通用解决方案。
luis.espinal,2010年

1

我的(简单的)两美分:

1:有ORMS,也有ORMS。一些ORMS基于Active Record,另一些基于Data Mapper-本身是一个相关的考虑因素,但是需要进行一些调查才能理解其含义。总的来说-我在PHP中的经验是ORMS支持前者,很少支持后者。基于Active Record的ORM似乎具有两种作用之一-它们要么对数据库进行反规范化,要么调用过多的类来支持对象交互。

2:ORM的优势与您需要运行的查询的复杂性直接相关性降低。如果您的关系很好,即用户->帖子,则它们可以很好地工作。这(IMO)是为什么大多数ORM /框架使用此类示例的原因。但是,当您需要运行复杂的查询时,您需要生成的ORMQL的数量可与常规SQL查询的字符串长度相比较-但由于运行查询的对象图会调用而导致性能降低,这不利于抽象。因此,简而言之-ORM对于您数据库任务的前30-50%非常出色-但对于最后一个任务却很糟糕。我认为这是AR如此流行的另一个原因。

3:为什么要从数据库中隐藏?您会使用服务器端语言来抽象javascript吗?

我个人将这些方法混合在一起:

  • 使用ORM作为基础,加载“用户”
  • 使用包含几个预烘焙的SQL查询的DAO(即selectLike,selectWhere)。
  • 在必要时扩展DAO以添加更具体但可重复使用的自定义查询
  • 通过DAO提供简单的数据库访问-即$ data = Dao-> query(您的sql字符串)以执行一次关闭查询。

说了这么多,Doctrine 2即将面世,这看起来真的很有趣。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.