代码改变世界

ORM之我的理解

2009-07-06 01:19  Tower Joo  阅读(4421)  评论(25编辑  收藏  举报

ORM之我的理解

摘要

本文主要介绍我对于 ORM 的一些理解, 关于ORM的讨论可以参见 TLSO.

内容如下:

ORM的定义

ORM (Object Relational Mapping, 对象关系映射)是一种在不同的数据库之上封装并提供一个统一的操作接口的 技术. ORM能够为用户提供统一的OO接口, 是 DAL (Data Access Layer, 数据访问接口)的一种实现方式.

ORM的应用场景

ORM为程序员提供了一个完整的访问数据库的接口, 并且是以程序员熟悉的 OO 方式来提供, 因而对于程序员而言, 能够很大的提高效率.封装于底层sql操作之上的ORM能够提供更加健状(更少的代码,意味着更少的错误)的数据访问机制,能够 在一定程度上提供安全的保证(防止sql注入等).

ORM通常用于:

  • 熟悉OO但不熟悉sql的程序员
  • 对sql性能要求不是太迫近
  • 有数据库迁移的需求
  • 知道ORM的底层的实现(事实上大多数程序是不知道的,并且自以为ORM已经做到最优,很可惜事实并非如此)

ORM的评价

ORM的提出及实现在工业上是具有极大意义的,它使得DBA和程序员的工作可以分开, 它使得程序员不必更多地关注数据库的细节, 而专注于事务逻辑的实现.

但, 任何层面的封装, 也就意味着程序员离实际目标(DB)更远, 性能也必将有所损失, 逻辑上也显得更加复杂.

而,对于数据库一个很重要应用领域的互联网应用, 绝大部分都是有大PV预期的, 因而当用户达到一定程序时, DB的访问必将成为性能瓶颈.因而这里就得 反思ORM的意义.

ORM的好处

ORM的好处也是显然的, 上面也已经提到了部分, 大致的好处如下:

  1. 提高开发效率,提高代码健状程度

    • 在互联网应用领域,快速出产品,继而迭代开发是十分重要的,谁先抢占市场,谁就更有机会成功.因而开发效率是至关重要的.
    • 使用ORM可以减少代码量, 而更少的代码意味着更健状, 因而也能够提高代码的健状性
    • 避免了提前优化的问题
  2. 为程序员提供一个完整的,统一的OO访问的接口, 使得程序员更加专注于事务逻辑而非DB的细节

    • 无论DB backend是什么, 都能够提供一个统一的OO接口
    • 让程序员能够使用相同的逻辑(毕竟sql和OO是不同的逻辑, 都使用OO也就避免了这种转换的成本,减少了出错的机率)
  3. 让程序员可以站在 一定的高度 (通常是可以看到影响应用性能的全局的问题),而进行全局的优化,而不至于陷入到 微优化 的trap中

    • 站的高度越高,通常意味着能够以更加宽视野的角度来处理问题中的瓶颈,而避免了只对细微不起主导作用的局部的优化(牵扯到优化的成本)
  4. 随着ORM框架的演进, 会提供愈加完善,高性能的支持

    • 有专业的ORM框架开发团队, 意味着有持续完善的,性能不断提高的ORM可用, 从而也逐步减少了下文提到的ORM的不足
    • 风险分担通常也是一种好的策略
  5. 简单,高效的数据库迁移

    • 当你有数据库迁移需求时, ORM的作用则显得无比的重要, 无需任何代码更改即可(与实际的ORM实现有关)
  6. 关于 eager loading (即一条操作将所有相关的数据一起取出来)

    • 这点技术还是太熟悉, 但是可以肯定的是 eager loading 能够在一定程度上提高效率,但是同样具有 黑盒 的味道

ORM的不足

  1. 性能的损失

    • ORM最终还是将一些OO操作映射到具体的sql语句,继而由DB执行, 因而sql语句的效率取决于ORM本身映射的实现,显然sql的透明性和灵活性已经失去
  2. 程序员依赖于ORM,而失去了 关键资源的控制权

    • 在性能要求很高时, DB的控制权则是关键资源, 而由ORM来 黑盒 (对于大多数程序员而言) 地转发sql显然是一种高风险的行为
  3. 学习成本

    • 如果程序员又要使用ORM又不想牺牲效率, 这时一种选择即是探究ORM的底层实现,知道哪些操作是 expensive 的,但是显然相比于只对sql的掌握,阅读ORM的源码的成本会更高,况且在知道了其内部原理后仍需熟悉sql

结论

我的结论是, 满足下面特征的应用推荐使用ORM(并非与的关系):

  1. 开发时间要求紧迫
  2. 有数据库迁移需求
  3. 了解ORM的内部实现

而满足下面特征的应用则推荐使用raw sql来开发:

  1. 效率要求高
  2. 无数据库迁移需求

后记

在和大家讨论过程中有朋友提到可以使用 存储过程 来提高DB效率, 初步了解后觉得也不失为一种好方法, 等自己对这个知识有一定理解后,在后续的博客中会探讨.