【发布时间】:2010-02-09 17:09:57
【问题描述】:
我还没有开始 ORM 之旅,
因为当项目变得非常复杂时,我不确定它是如何工作的。
你有什么意见或经验?
【问题讨论】:
我还没有开始 ORM 之旅,
因为当项目变得非常复杂时,我不确定它是如何工作的。
你有什么意见或经验?
【问题讨论】:
这个问题有时很难回答。您之前可能听说过Object-Relational Impedance Mismatch;这是 ORM 工具试图解决的问题,但它充满了问题。在这种情况下,您可以在很短的时间内解决 90% 的问题,但此后每增加 1%,复杂性似乎会因为所有依赖项而呈指数级增加。
ORM 框架是一种抽象,并且在几个点上变成了一个有漏洞的抽象:
涉及 UDT、CTE、查询提示、临时表、窗口函数等概念的复杂查询/脚本。
性能优化查询。正如 Quassnoi 在他的回答中提到的,ORM 在这方面做得越来越好,但经常会生成次优查询,有时效果非常明显。
事务管理 - 工作单元模式仅在您必须处理大批量更新时才能帮到您。
跨数据库或跨服务器操作。有一些变通方法,但它们只是 - 变通方法。我见过的没有一个 ORM 能很好地处理这个问题。
多表继承 - 这是真正规范化的唯一继承形式,使用纯 SQL 和手动映射确实不难管理,但 O/R映射器很糟糕。对于我们中的许多人来说,单表继承不是一个可接受的替代方案。
这些是 O/R 映射器似乎让我们失望的许多领域中的一部分。话虽如此,这并不意味着 O/R Mappers 不“适合”大型项目。
在我看来,一般的 ORM 和具体的 O/R 映射器对于大型项目几乎是至关重要的。它们节省了大量的精力,并且可以帮助您在很短的时间内完成应用程序。他们只是没有解决整个问题。您必须准备好分析您的应用程序以了解 ORM 真正在做什么,并且您必须准备好在情况需要时(即在上述几种情况下)退回到纯 SQL。
某些框架(例如 Linq to SQL)希望您这样做,并为您提供现成的工具,用于在用于映射器“常规”职责的同一连接和同一事务中执行命令或存储过程。 L2S 并不是唯一允许您执行此操作的框架,但有几个框架更具限制性,您最终会跳过很多圈才能获得所需的内容。在选择 ORM 时,我认为绕过抽象的能力是一个重要的考虑因素,至少在今天是这样。
我认为这个问题的最佳答案是:是的,它们适用于大型项目,只要您不完全依赖它们。了解您选择的 ORM 工具的局限性,尽可能在 90% 的实例中使用它来节省时间,并确保您和您的团队了解抽象泄漏时这些实例的幕后实际情况。
【讨论】:
ORM。根据定义,是对象关系映射。
这意味着您应该将存储在关系数据库中的数据转换为面向对象编程语言可用的对象。
对象可能提供一些可能涉及数据处理和搜索其他对象的方法。
这就是问题的开始。
数据处理可以在ORM端实现(这意味着从数据库加载数据,应用对象环绕并在您使用的编程语言上实现方法),或者在数据库端(当数据处理命令作为对数据库的查询发出)。
比较一下:
MyAccount->Transactions()->GetLast()
这可以通过两种方式实现:
SELECT *
FROM Accounts
WHERE user_id = @me
转入$MyAccount
,然后
SELECT *
FROM Transactions
WHERE account_id = @myaccount
进入客户端数组@Transactions
,然后$Transactions[-1] 获得最后一个。
这是一种低效的方式,当您获得更多数据时您会注意到它。
或者,智能ORM 可以将其转换为:
SELECT TOP 1 Transactions.*
FROM Accounts
JOIN Transactions
ON Transactions.Account = Accounts.id
WHERE Accounts.UserID = @me
ORDER BY
Transactions.Date DESC
,但它必须是一个非常聪明的ORM。
所以“是否使用ORM”这个问题的答案是“我的ORM 是否允许我在需要时向数据库发出基于集合的操作”这个问题的答案?
【讨论】:
ORM 永远不会出错的候选人?
这是主观的。我的回答专门针对自动化 ORM 工具。
我对 ORM 工具有一个哲学上的反对,原因如下:
1- 表不是也不应该是与业务对象的一对一映射。
2- 基本 CRUD/业务对象代码编写起来很无聊,但它对您的应用程序至关重要。我宁愿控制并了解它。 (有点 NIH 综合症)
3- 与 ORM 工具创建的任何奇怪语法相比,新加入的开发人员将更容易学习传统的对象模型。
【讨论】:
您没有提及您使用的是什么平台,但如果我想在不使用 ORM 的情况下从 .NET 中的数据库中读取记录,我将不得不:
听起来很复杂? ORM 在后台自动完成所有相同的事情,而我只需要几行代码。此外,由于 ORM 了解您的数据模型,它有时可以执行优化,例如缓存和延迟加载。
【讨论】:
当项目变得更复杂时它会更好,因为它让我们将所有内容都保持在同一抽象级别,而不是从对象跳转到 SQL。我们曾经编写了自己的层来并行开发应用程序(因为我们不能使用任何传统的 ORM),并且它变得越强大,管理应用程序变得越容易。
您通常高估了性能问题。它通常在不同的地方,然后你会期望。我们有一些用 Python 编写的糟糕抽象层,它运行良好。糟糕的是 url 库,我们不得不用 C 重写它。真的,你总是可以优化最后最重要的查询,此时手动编写 SQL,当你看到时,性能需要它。但在大多数情况下,您不必这样做。
【讨论】:
在我看来,ORM 是为大型项目而构建的,可以最大限度地减少工作量和开发时间。
但是,如果您正在开发一个需要非常高速数据访问代码的应用程序,则需要尽可能避免使用 ORM,因为 ORM 在您的应用程序中添加了一个新层
【讨论】:
ORM 非常适合大型项目,因为它们在数据库端提供了一层保护以防止更改,并加快了添加新功能的过程。如果性能成为问题,您可以使用不同的方法在遇到瓶颈的查询处获取数据,而不是手动优化应用程序中的每个查询。
【讨论】:
如果您想快速抽出网络应用程序来进行客户开发并查看人们是否真正使用您的产品,那么 ORM 非常棒。
http://www.youtube.com/watch?v=uFLRc6y_O3s
Josh Berkus 讨论的最后一个主题是“失控的 ORM”。请在 37:20 观看。
【讨论】: