内容简介:Object Relational Mapping,对象关系映射,一般简写为O/RM,或者更常见的ORM,就是数据库里面的一条记录,映射到一个对象,记录里面的字段,成为对象的属性。这是面向对象的数据访问方式。在没有O/RM之前,我们习惯使用代码生成器来根据表结构自动生成各种CRUD(增删查改)方法。但是,这只能满足简单的操作,当业务复杂起来,特别是关系型数据,这个方法捉襟见肘。不同的技术栈有不同O/RM方案,譬如Python的SQLAlchemy、Java的JPA(Java Persistence API)
O/RM
Object Relational Mapping,对象关系映射,一般简写为O/RM,或者更常见的ORM,就是数据库里面的一条记录,映射到一个对象,记录里面的字段,成为对象的属性。这是面向对象的数据访问方式。
在没有O/RM之前,我们习惯使用代码生成器来根据表结构自动生成各种CRUD(增删查改)方法。但是,这只能满足简单的操作,当业务复杂起来,特别是关系型数据,这个方法捉襟见肘。
不同的技术栈有不同O/RM方案,譬如 Python 的SQLAlchemy、 Java 的JPA(Java Persistence API)这个O/RM标准接口的就有多个解决方案。.NET下有从Java的Hibernate移植过来的NHibernate、微软开源的Entity Framework(EF)、Dapper、PetaPoco等。说起Hibernate,几年前12306售票系统出现问题,说是用的Hibernate。
Jeff Atwood是计算机编程博客Coding Horror的博主。他共同创建了计算机编程问答网站Stack Overflow,并共同创建了Stack Exchange。他曾经说过 “O/RM是计算机科学的越南战争” 。
优势
生产力的提高
- 用更少的代码,简便地实现CRUD(增删查改)
- 多表连接可以方便地使用对象关系方式访问因为是面向对象,编译时便可知道一些用纯 SQL 可能会遇到的拼写、语法错误。这个有点像TypeScript和JavaScript的关系
- 在Visual Studio等IDE中,在进行调试的时候,方便地浏览关系型对象因为最终执行的SQL是自动生成的,所以不受代码风格约束,而且只要合理使用O/RM,类似SQL注入等容易在手写SQL遇到的,不是一个大问题
- 因为数据抽象访问,所以带来了支持多种数据库的可能性,譬如从PostgreSQL切换到SQL Server
缓存:双刃剑
- 优秀/流行的O/RM内置了对缓存的支持,这样可以减少重复的数据库访问
- 但是,一些时候你忘记了刷新已经缓存了的对象,你将会遇到数据版本冲突问题(老数据覆盖了较新的数据),一般做法是在必要的地方都调用类似Refresh等方法来刷新,但这样比较蹩脚
缺点
性能约束
- 初始化加载,视乎你使用Code-first、Model-first还是Database-first,背后在做大量的工作,确保模型映射和数据库架构一致。某司使用NHibernate,几百个model,每次初始化需要3-5分钟
- N+1问题:父子表关系,映射/使用错误,可能会导致父表的每条记录都会在子表做一次查询,譬如父表有1000条记录,最终可能会产生1001条查询
- 类似报表中使用的各种聚合、pivoting(行列转换)
- 要达到理想的性能,你需要调整各种映射属性,甚至做所谓的hacking,譬如模型定义了一些子表关联,如果你不想获取,你可能需要把这些属性设置为空值,或者设置为延迟加载;如果你熟练掌握SQL, 你会发现手写SQL会来得容易很多
- 批量数据处理:批量导入/更新、导出,真要使用,一般O/RM需要蹩脚的处理
高级功能的缺少/支持
- 譬如游标、递归、特定类型(如自定义类型)的支持
- 譬如SQL Server的OUTPUT等的支持
- 复杂查询,或者一些窗口函数, O/RM要么不支持这意味着你必须传输额外的数据在业务层进行处理,要么会很别扭。这个时候,用存储过程就更加合理
维护的难度
O/RM一个重要的特性,也是必备,就是数据库和对象之间的映射,数据库表、字段的特性,譬如字段的最大长度、各种约束(最大、最小值、默认值等)、精度、外键等,都要一一定义,不管是通过类似Hibernate的XML还是Fluent Hibernate的面向对象方式,或者一些Model-first的通过特性(attribute)来实现。
O/RM的使用,会导致两套数据库结构,一套在数据库里面,一套在O/RM定义。当你需要改动结构,你需要实现迁移,譬如改改变了字段的名字、表名。
使用的成本
使用O/RM的一个目的是只需要关心业务,不需要放多少时间在SQL上面,但是,学习O/RM本身是需要时间的,而且,要用好O/RM,不可避免要学好SQL,所以这个学习时间可能是单纯学习SQL的两倍或者更多。
之前说生产力是O/RM的优势,但是这个是建里在你必须先把映射关系建立好的基础之上,这个过程视乎业务系统的复杂度,需时可能比较长
数据库的表结构很多时候无法和对象模型完整一致,导致了在使用过程中需要做手工的转换,模型也随之快速增大,增加了逻辑的复杂性
之前说O/RM可以切换数据库系统,但是当你把一个数据库系统真的用起来之后,你会发现,你很大机会需要用到数据库系统的一些特性,这是其它数据库系统没有的,那么,这个迁移将会很大的挑战性。越抽象,复杂度越高,成本也随着增加
最佳实践
如果你希望深入了解数据库访问、O/RM最佳实践, 跟随有15年+经验的数据库专家手把手、全程实战、系统性地、快速学习和提高数据库开发技术 ,欢迎访问 DevYeah.com 联系我们。
交互式学习平台
本文完整版本在Dev Yeah的交互式学习平台上,有兴趣的同学可以 点击这里免费注册,马上免费试用Dev Yeah的各种技术教学视频!
每日技术精选
Dev Yeah推出全新服务:每日技术精选。
不同的技术人有不同的阅读/学习习惯,一些一天读几篇甚至多篇文章,但是:
- 由于时间限制,花了时间阅读才发现要么文章质量不高或者晦涩难懂,不能高效地学习
- 日积月累,之前看过喜欢的文章,现在找不回来了
Dev Yeah的每日技术精选,包括但不限于:业界新闻、新/优秀开源项目、优秀技术文章等。分类包括前端、后端、数据存储、安全、AI/大数据等
每天我们会重点对其中一篇内容进行精读概述,让大家能够更好地理解、掌握和提高技术水平。
点击这里免费注册,马上免费试用Dev Yeah的每日技术精选!
Dev Yeah 全栈课程
要系统、快速、全面提高您的技术水平吗?访问 Dev Yeah 了解我们提供的 全栈(前端、后端、数据存储和必备等) 和 Python数据科学课程 !15+年全栈开发经验(Web前端、后端、数据库、必备等)的技术专家手把手、全程实战!
扫描下面的二维码加入Dev Yeah技术交流群
扫描下面的二维码联系Dev Yeah客服
版权所有
所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。
以上所述就是小编给大家介绍的《O/RM的优势、缺点和最佳实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。