大型、可扩展和可维护的 Web 应用程序中的 ORM 或 SQL?

Posted

技术标签:

【中文标题】大型、可扩展和可维护的 Web 应用程序中的 ORM 或 SQL?【英文标题】:ORM or SQL in large, scalable and MAINTAINABLE web application? 【发布时间】:2010-04-14 12:23:50 【问题描述】:

我知道网上已经有很多关于这个话题的帖子了。

但是,许多人在谈论它时倾向于关注不同的事情。我的主要目标是创建一个易于维护的可扩展 Web 应用程序。开发和维护的速度比原始性能更受我的赞赏(或者我可以使用 Java 代替)。

这是因为我注意到当一个项目的代码量增加时,你必须有可维护的代码。当我第一次以程序方式编写我的应用程序时,没有任何框架,仅在 1 个月后它就变成了一场噩梦。我完全迷失在意大利面条代码行的丛林中。我根本没有任何结构,即使我努力实现一个结构。

然后我意识到我必须以正确的方式构建结构和编码。我开始使用 CodeIgniter。这真的给了我结构和可维护的代码。很多用户说框架正在减慢速度,但我认为他们忽略了这一点。代码必须可维护且易于理解。

Framework + OOP + MVC 使我的 Web 应用程序如此结构化,因此添加功能不再是问题。

当我创建一个模型时,我倾向于认为它代表一个数据对象。也许是一个表格,甚至是一个表/数据库。所以我想到了ORM(学说)。也许这将是我的 Web 应用程序的又一个很好的实现,赋予它更多的结构,这样我就可以专注于功能而不是重复自己。

但是,我以前从未使用过任何 ORM,我只了解了它的基础知识,为什么它好用等等。

所以现在我问你们所有和我一样都在努力开发可维护代码并且知道这有多重要的人,ORM(原则)对于可维护代码是否必须具备,就像 framework+mvc+oop 一样?

我想要比“原始 sql 更快”的建议更多的生活经验建议,因为如果我只关心原始性能,我应该首先放弃 framework+mvc+oop 并继续生活在编码噩梦中。

感觉它非常适合模型就是表格的 MVC 框架。

现在我在一个文件中有大约 150 个 sql 查询,它们执行简单的操作,例如按 id 获取条目、按名称获取条目、通过电子邮件获取条目、通过 X 获取条目等等。我认为 ORM 可以减少这些行,否则我很确定将来这将增长到 1000 条 sql 行。如果我在一列中更改,我必须更改所有列!想想这又是一场噩梦。也许这也可以为我提供适合 MVC 模式的好模型。

ORM 是构建结构和可维护代码的正确方法吗?

【问题讨论】:

你确定你提到 MAINTAINABLE 的次数够多了吗?如果没有更多的上限,人们可能无法理解您的观点。 很抱歉,这是一场无法维护的编码噩梦。所以在不知不觉中强调了太多次:) 【参考方案1】:

阿杰,

我投票支持 ORM。我使用 NHibernate。它并不完美,并且有相当大的学习曲线。但是代码更易于维护,更多的是面向对象的。除非你喜欢大量重复的代码,否则几乎不可能在没有 ORM 的情况下使用 OOP 创建应用程序。它肯定会消除您的绝大多数 SQL 代码。

还有另一件事。如果您要构建一个 OOP 系统,无论如何您最终都会编写自己的 O/R Mapper。您需要调用动态 SQL 或存储过程,将数据作为读取器或数据集获取,将其转换为对象,连接与其他对象的关系,将对象修改转换为 sql 插入/更新等。您编写的内容将是比 NHibernate 或市场上已经存在很长时间的东西更慢、更容易出错。

您唯一的其他选择确实是构建一个以数据为中心的程序化应用程序。是的,它可能在某些领域执行得更快。我同意性能很重要。但重要的是它的速度足够快。如果您在这里和那里节省几毫秒的时间来编写程序代码,您的用户将不会注意到性能提升。但是你会注意到蹩脚的代码。

ORM 中最大的性能瓶颈在于预取和延迟加载对象的正确方式。这涉及到 ORM 的 n 查询问题。不过,这些都很容易解决。您只需要调整对象查询的性能并限制对数据库的调用次数,告诉它何时使用连接等。NHibernate 还支持丰富的缓存机制,因此您根本不会访问数据库。

我也不同意那些说性能关乎用户而维护关乎编码员的说法。如果您的代码不容易维护,那么添加功能将是错误的和缓慢的。您的用户会关心这一点。

我不会说每个应用程序都应该有一个 ORM,但我认为大多数应用程序都会受益。也不要害怕在必要时时不时地使用原生 SQL 或带有 ORM 的存储过程。如果您必须对数百万条记录进行批量更新或编写一个非常复杂的报告(希望针对一个单独的、非规范化的报告数据库),那么直接使用 SQL 是可行的方法。将 ORM 用于 OOP、事务、业务逻辑和 C.R.U.D。的东西,并使用 SQL 处理异常和边缘情况。

我建议阅读 Jeffrey Palermo 关于 NHibernate 和 Onion 架构的资料。此外,参加他的敏捷训练营或其他课程来学习 O/R 映射、NHibernate 和 OOP。这就是我们使用的:NHibernate、MVC、TDD、依赖注入。

【讨论】:

你说的太对了。在使用 MVC 时,我几乎自己写了一个 ORM!然后我想“这不是 ORM 的作用”:) 我想知道使用 MVC 的编码人员是如何进行 CRUD 的?如果他们有一个名为“用户”的模型。然后他们只是为 CRUD 提供了一些方法?对于所有列,这意味着很多 sql 查询。我不使用.net,而是使用 php。所以我想我最好的选择是 Doctrine,因为很多程序员都在投票支持它。【参考方案2】:

很多用户说框架是 放慢速度,但我认为他们 错过了大局。代码必须 易于维护 明白。

一个结构良好、高度可维护的系统,如果它的性能很糟糕,那就毫无价值了!

可维护性有利于构建应用程序的编码人员。原始性能使使用该应用程序进行工作(或其他)的真实人员受益。那么,谁最关心的是:构建系统的人还是支付费用的人?

我知道事情没有那么简单,因为客户最终会为一个结构不佳的系统买单 - 可能会有更多的错误,当然还有更多的时间来修复它们,更多的时间来实现应用程序的增强功能。通常情况下,一切都是一种权衡。

【讨论】:

100% 同意。这是问题的核心。开发人员似乎认为拥有一个易于维护的系统(因为他们不熟悉原始 sql)对他们来说比让最终用户真正拥有一个高性能的系统/体验更重要。它使头脑感到困惑。【参考方案3】:

我已经开始像你一样开发,没有 orm 工具。

然后我在软件开发更加工业化的公司工作,他们都使用某种 orm 映射工具(或多或少的功能)。开发更容易、更快、生成更多可维护的代码等。

但我也看到了这些工具的缺点:性能非常慢。但这主要是工具的滥用(在这种情况下是休眠)。

Orm 工具是非常复杂的工具,因此很容易被误用,但如果您有使用它们的经验,您应该能够获得与使用 raw sql 几乎相同的性能。我想给你三个建议:

如果性能不重要,使用orm工具(选择一个好的,我不是用php开发的,所以我不能给你一个名字) 确保为您添加的每个功能检查 orm 工具生成并发送到数据库的 sql(例如,感谢日志记录工具)。想想这是否是您编写查询的方式。 orm 工具的大部分低效来自于从数据库中收集的不需要的数据、独特的请求拆分为多个等。缓慢很少来自工具本身 不要对所有事情都使用该工具。明智地选择何时不使用它(每次进行原始数据库访问时都会降低可维护性),但有时,尝试让 orm 工具做一些不是为它开发的事情并不是最糟糕的。

编辑: Orm 工具对非常复杂的模型最有用:实体之间的许多关系。这是大多数时候在应用程序的配置部分,或者在应用程序的复杂业务部分遇到的。 因此,如果您只有很少的实体,并且它们被更改(重构)的可能性较小,那么它的用处就会降低。

少数实体与多数实体之间的界限尚不清楚。我会说 50 种不同的类型(sql 表,没有连接表)很多,少于 10 种很少。

我不知道用什么来构建 ***,但它之前一定经过了非常仔细的性能测试。

如果您想构建一个负载如此之重的网站,并且如果您没有这方面的经验,请尝试在您的团队中找一个已经在此类网站上工作过的人(使用真实的性能测试一组数据和一个有代表性的并发用户数量并不是一项容易快速实现的任务)。有经验的人会大大加快这个过程。

【讨论】:

@thierry。什么是 ORM 不打算做的事情?和性能相比会真的很慢吗?如果我们谈论的是***大小。那么我不应该在任何地方使用 ORM 吗? 作为一名拥有 17 年经验的开发人员,拥有许多大型系统的经验,我可以确认 ORM 在任何大型/数据密集型系统中都比 SQL 慢几个数量级。 数量级(x100?)可能有点夸大了orm的成本(如果您使用的ORM是这种情况,请更改为另一个)。另外,您是说当您通过 ORM 运行 SQL 查询时,它比使用语言原语/标准库运行相同查询要慢几个数量级?为正确的事情使用正确的工具。 7 年后,我仍然认为到处写原始 sql 是过早的优化。使用好的 ORM 工具,如果通过它为给定用例生成东西太慢,则转到该用例的 SQL 级别。【参考方案4】:

拥有高可维护性非常重要。我开发了具有低级超高性能的大型 Web 应用程序。最大的缺点是维护系统,即开发新功能。如果您要放慢开发速度,客户会寻找其他系统/应用程序。它是一种交易。如果您需要直接对 sql 进行优化查询,大多数 orms 都具有功能。 orm 本身不是瓶颈。生病说它更多关于一个好的数据库设计。

【讨论】:

【参考方案5】:

我想你错过了这张照片。性能对您的用户来说是每天的事情,他们根本不关心可维护性。你是以种族为中心的,你只关心你的个人问题,而​​不是那些为系统买单的人的问题。这不仅仅是为了您的方便。

也许您应该与用户坐下来,观察他们使用您的系统一两​​天。然后,您应该坐在与他们使用的计算机(而不是开发机器)具有相同功能的 PC 前,并花一整周的时间除了整天使用您的系统之外什么都不做。那么你可能会理解他们的观点。

【讨论】:

你在这里非常冒犯。我只是指出如果你有可维护的代码,那么你可以维护它:) 如果你有很多开发人员并且他们无法理解它,或者代码非常混乱(没有框架、oop、mvc)那么你不能添加/edit/remove 功能很容易,并且应用程序不如预期的那么好。我想知道 ORM 是否可以给我这个优势。 完全同意你的 ajsie。如果可维护性可以降低添加功能的成本,那么对客户也有好处(他们会花更少的钱)。因此,您在原始性能和代码可读性之间进行权衡是完全有意义的 @thierry。感谢队友理解我的观点。在没有任何结构的情况下,我什至无法理解自己的代码。这就是我努力维护可维护性的原因。 你的态度冒犯了你的用户。可维护性不是系统需要的首要质量,可用性才是。 我对用户有很多想法……奇怪的是你声称我没有。你知道它是什么样的应用程序吗?我的应用程序很有用......并且可维护:)

以上是关于大型、可扩展和可维护的 Web 应用程序中的 ORM 或 SQL?的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别