一万小时 / ORM之我的理解
ORM之我的理解
ORM之我的理解
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的好处也是显然的, 上面也已经提到了部分, 大致的好处如下:
-
提高开发效率,提高代码健状程度
- 在互联网应用领域,快速出产品,继而迭代开发是十分重要的,谁先抢占市场,谁就更有机会成功.因而开发效率是至关重要的.
- 使用ORM可以减少代码量, 而更少的代码意味着更健状, 因而也能够提高代码的健状性
- 避免了提前优化的问题
-
为程序员提供一个完整的,统一的OO访问的接口, 使得程序员更加专注于事务逻辑而非DB的细节
- 无论DB backend是什么, 都能够提供一个统一的OO接口
- 让程序员能够使用相同的逻辑(毕竟sql和OO是不同的逻辑, 都使用OO也就避免了这种转换的成本,减少了出错的机率)
-
让程序员可以站在 一定的高度 (通常是可以看到影响应用性能的全局的问题),而进行全局的优化,而不至于陷入到 微优化 的trap中
- 站的高度越高,通常意味着能够以更加宽视野的角度来处理问题中的瓶颈,而避免了只对细微不起主导作用的局部的优化(牵扯到优化的成本)
-
随着ORM框架的演进, 会提供愈加完善,高性能的支持
- 有专业的ORM框架开发团队, 意味着有持续完善的,性能不断提高的ORM可用, 从而也逐步减少了下文提到的ORM的不足
- 风险分担通常也是一种好的策略
-
简单,高效的数据库迁移
- 当你有数据库迁移需求时, ORM的作用则显得无比的重要, 无需任何代码更改即可(与实际的ORM实现有关)
-
关于 eager loading (即一条操作将所有相关的数据一起取出来)
- 这点技术还是太熟悉, 但是可以肯定的是 eager loading 能够在一定程度上提高效率,但是同样具有 黑盒 的味道
ORM的不足
-
性能的损失
- ORM最终还是将一些OO操作映射到具体的sql语句,继而由DB执行, 因而sql语句的效率取决于ORM本身映射的实现,显然sql的透明性和灵活性已经失去
-
程序员依赖于ORM,而失去了 关键资源的控制权
- 在性能要求很高时, DB的控制权则是关键资源, 而由ORM来 黑盒 (对于大多数程序员而言) 地转发sql显然是一种高风险的行为
-
学习成本
- 如果程序员又要使用ORM又不想牺牲效率, 这时一种选择即是探究ORM的底层实现,知道哪些操作是 expensive 的,但是显然相比于只对sql的掌握,阅读ORM的源码的成本会更高,况且在知道了其内部原理后仍需熟悉sql
结论
我的结论是, 满足下面特征的应用推荐使用ORM(并非与的关系):
- 开发时间要求紧迫
- 有数据库迁移需求
- 了解ORM的内部实现
而满足下面特征的应用则推荐使用raw sql来开发:
- 效率要求高
- 无数据库迁移需求