为什么不推崇复杂的ORM
上一篇文章写完,回复的人很多,有的说的很中肯,有的貌似只是看到文章的标题就进来写评论的!还有人问为什么我要屏蔽掉【反对】按钮,因为谁写文章都是为了分享,都在说出自己的心得体会。不过由于大家遇到的项目,做的东西,见过技术各有差异,很难让每个人都向一种意见靠拢。所以你可以不喜欢,但是请不要作恶!
评论中*深海, lindping说的是通用的ORM可以为通用产品带来部署的便利!dax.net,深蓝医生,路过秋天说的是ORM一个很关键的作用就是可以加快开发速度!还有些属于性能控,对SQL比较推崇。还有些没有明白表达的意图,语文是音乐老师教的!实在抱歉!
先说下部署这个问题,如果是做通用产品的话,考虑到各种数据库的兼容确实能带来很多好处。这一点我很认同,不过从业开始但现在,接触过的项目基本上都是属于定制类的,所以这一点没能感同身受。有过一次,不过不是换数据库这么简单,而是换整个部署方案,从WINDOW平台换到LINUX上,数据库从MSSQL换成ORACLE。没用ORM,用的SQLSHOP+存储过程的方式来做的系统,前后一个星期全部完工。因为SQLSHOP的SQL都是可以人工干涉的,存储过程这一类的调用也是放在SQLSHOP里面,所以我们基本上没有动一行代码,都是通过机器生产和人工的方式来修改存在XML里面的SQL,效果还可以。也是因为这次的经历,我才发现原来MSSQL和ORACLE其实差不了多少,存储过程,SQL函数,调用的语法,性能等等.Mono加JEXUS,有时比IIS还给力。
开发效率是评论中比较让我纠结的。因为我不是说我不用ORM,而是我觉得ORM设计的太复杂,没有什么太大的意义(原文第四句哈)!
主流的数据库,其增【INSERT INTO . (.,.)VALUES(.,.)】,删【DELETE FROM . WHERE ...】,改【UPDATE . SET .=. WHERE .=.】的语法都一样,这部分可以抽象,做出一个支持CUD(没有R)的系统。
但是查询就不是那么简单了,人们对数据的关注点不一样,所以需要的查询语句就不相同。不是所有主流数据库都有一个相同的查询系统,所以这一部分很难抽象。
所以没有一套ORM能很完美的处理了查询问题。
1.语法上,没法做到比SQL更简洁。
2.语义上,各库SQL方言的差异很大。你需要为每个主流数据库写一套不同的SQL方言系统,你需要了解各种库SQL的特点。
3.语用上,你需要动态生成符合当前情景的SQL。比如你做分页,每种库纯SQL的分页方言就有很多,每种分页在不同的分页情景下效率是不同的,最优的情况是你可以动态去判断情景。
上述三点,不说第三点。前两个弄得很好的ORM,开源的NHibernate没有做到,微软自己的EF没有做到,商用的LightSpeed也没有做到。目前的ORM都是在1和2上下功夫。3很难,而且对需求如此苛刻的也不会使用ORM了。所以,我倒是觉得与其活生生的坑在这三点上,倒不如从以下几个方面好好考虑一下,数据库支持,功能支持,语法支持,映射支持等。比如:
1.考虑下NOSQL吧,可以做完整单表映射或NOSQL数据的对象映射。
怎么支持RavenDB,STSdb,MongoDB,Cassandra等?
2.考虑下DDD吧。功能齐全的CUD系统,能否很好的支持CQRS中C?
怎样快速从数据库中映射出运行时对象?反射,EMIT,表达式?
怎么提高缓存的命中?支持Memcached,还是使用自己实现的?
3.考虑下支持OO原生特性,因为需要拿ORM来表达业务流程,是站在OO的角度考虑问题而不是数据库。那么你的ORM就需要考虑一些数据库问题了。
怎样为有继承关系的对象设计表?共享同一张表,还是分开,然后使用字段关联?
怎样选择更新时的充血或贫血?充血和贫血都有优缺点,怎样选择?
业务对象是可以用户实例化的还是只能由ORM实例化?用户实例化和ORM实例化各有各的好处,选择哪个?
可否为对象及对象的属性添加拦截?能够知道系统中最热对象是哪个,最热属性是哪个,由此可以得出一些很有意思的信息在,怎么设计?
......
这实在是太多了,不管是细节还是宏观上,都太多了。
4.考虑下支持从数据库直接映射成XML或JSON吧,或把XML或JSON直接转换为SQL吧,虽然XML和JSON不是对象,但是越来越多的地方使用XML或JSON来做对象容器。
说完查询SQL生成的复杂,再说业务逻辑的问题。把复杂逻辑放在代码,还是放在数据库里面。其实这个也很让人纠结。站在数据库的角度想,在离数据越近的地方处理数据越快,所以放在数据库里面吧。但是站在代码的角度考虑,各种对象组合在一个表达了一套完整的业务流程,用OO的方式去考虑这个流程远比使用数据库表结构去表达要好很多,所以放在代码里面吧!......评论中地狱门神的评论很直接,我也很想这么做。但是有时候,完全使用代码去完成一套业务流程是不靠谱的。使用存储过程的时候,一切都是在数据库中,少了从数据库表到运行时对象的转换,肯定会快很多。而且业务流程越复杂,这一点体现的越明显。如果你的系统中有个部分是和很多表关联的,比如权限模块,你用ADO.NET到OBJECT,再处理OBJECT,再使用OBJECT和ADO.NET获取新的OBJECT的这种串行化的方式处理业务流程,当表的关联到达一定程度的时候,那个速度是完完全全不能忍受的。这个时候就需要使用存储过程了。
所以根据以往的经验,使用存储过程的地方主要是两点。
1.如果有部分的业务变化比较频繁并且有一些性能要求,使用存储过程吧,这样在系统运行时就能轻松的修复一些问题。
2.如果一个流程关联的表比较多(多于3张以上的表),而且每个表的数据都超过1W,那么也用存储过程吧。
如果对性能要求不高,表关联也不多,业务流程很简单,那就可以使用代码的方式来表达业务流程了。
所以,想想吧!
复杂查询SQL,就算是再复杂的ORM也玩不来的,与其如此,倒不如设计的简单易用些。
不要再为ORM考虑怎么全部的CURD都是对象操作,怎么全部的查询SQL都是自动生成,怎么设计支持多表关联了。
作为程序员,何必活的那么复杂,大道至简!
补加一段我下午5点的评论(评论31楼)!
现在所有的ORM都是以解决对象的CURD为目标的!
但是!
数据库集群的时候,读写分离!
CQRS中把C和Q会分开!
所以!
原本R和CUD就不是一类,但是非要用ORM来动态生成!
生成的结果又也不一定好,也不能充分体现每种数据库自己的优势!
与其如此,倒不如把CUD做好,把R外置出去,做到可以人为干涉!
因为我自己一直在做ORM,也希望做的完美!
C#写的ORM,我用过的不一定你都用过!
用的越多,自己做的时间越长就越觉得R和CUD不是一类!
所以就希望把R从ORM中外置除去,做到所有生成的SQL可以手动干涉!
开发效率不会比你直接调ORM的SQL慢,但是效率绝对不比你慢,修改绝对比内置在ORM内部要方便,觉得那个SQL生成的不好,还可以手动去改!
这就是把R和CUD分出去的好处!
现在的ORM,那个能做到这么灵活!
为什么不推崇复杂的ORM的更多相关文章
- 用事实说话,成熟的ORM性能不是瓶颈,灵活性不是问题:EF5.0、PDF.NET5.0、Dapper原理分析与测试手记
[本文篇幅较长,可以通过目录查看您感兴趣的内容,或者下载格式良好的PDF版本文件查看] 目录 一.ORM的"三国志" 2 1,PDF.NET诞生历程 2 2,Linq2 ...
- (转)用事实说话,成熟的ORM性能不是瓶颈,灵活性不是问题:EF5.0、PDF.NET5.0、Dapper原理分析与测试手记
原文地址:http://www.cnblogs.com/bluedoctor/p/3378683.html [本文篇幅较长,可以通过目录查看您感兴趣的内容,或者下载格式良好的PDF版本文件查看] 目录 ...
- 所有设计复杂的ORM都是浮云
很久没有写文章了. 一直很忙,不是很有时间整理. 今天主要是来吐槽下那些设计很复杂的ORM的. 项目做的越多,越觉得ORM这个东西设计的太复杂实在是没什么意义. 比较推崇Dapper这样比较简单,效率 ...
- Python3+SQLAlchemy+Sqlite3实现ORM教程
一.安装 Sqlite3是Python3标准库不需要另外安装,只需要安装SQLAlchemy即可.本文sqlalchemy版本为1.2.12 pip install sqlalchemy 二.ORM操 ...
- 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework
[前言] 接上一篇<[原创]打造基于Dapper的数据访问层>,Dapper在应付多表自由关联.分组查询.匿名查询等应用场景时不免显得吃力,经常要手写SQL语句(或者用工具生成SQL配置文 ...
- 终于等到你:CYQ.Data V5系列 (ORM数据层)最新版本开源了
前言: 不要问我框架为什么从收费授权转到免费开源,人生没有那么多为什么,这些年我开源的东西并不少,虽然这个是最核心的,看淡了就也没什么了. 群里的网友:太平说: 记得一年前你开源另一个项目的时候我就说 ...
- Enterprise Solution 3.1 企业应用开发框架 .NET ERP/CRM/MIS 开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms
行业:基于数据库的制造行业管理软件,包含ERP.MRP.CRM.MIS.MES等企业管理软件 数据库平台:SQL Server 2005或以上 系统架构:C/S 开发技术 序号 领域 技术 1 数据库 ...
- UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?
选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...
- 搭建一套自己实用的.net架构(3)续 【ORM Dapper+DapperExtensions+Lambda】
前言 继之前发的帖子[ORM-Dapper+DapperExtensions],对Dapper的扩展代码也进行了改进,同时加入Dapper 对Lambda表达式的支持. 由于之前缺乏对Lambda的知 ...
随机推荐
- linux标准daemon编写方式
daemon定义 运行在后台的程序,通常不需要与用户进行交互的. 任何父进程id是0的通常是kernel进程,作为系统启动的一部分,除了init是用户态的命令. 规则 第一件事情是调用umask设置文 ...
- 公钥、私钥、CA认证、数字签名、U盾
感谢传智播客的方立勋老师,在一个教学视频上,他巧妙地以蒋介石给宋美龄写密信作为例子,生动地讲述了软件密码学知识. 加密分为对称加密和非对称加密,我们传统理解的,发送数据之前使用一个加密器加密,接到数据 ...
- Android之TextView密码输入变星号时间
private static class Visible extends Handler implements UpdateLayout, Runnable{ public Visible(Spann ...
- linux samba 服务配置及日志管理
2012-01-16 安装samba共需3个rpm包 samba-common-3.0.23c-2.i386.rpm samba-3.0.23c-2.i386.rpm samba-cli ...
- mongodb备份恢复
注意:在备份文件存放目录的选择上有这样一个条件,文件存放目录不管有多深,都只能有它一个文件:(即除了备份文件之外只能存在文件夹,这个条件约束其整个目录树) 数据备份 : /mongodump --ho ...
- Oracle 物化视图 说明
一. 物化视图概述 Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表.物化视图存储基于远程表的数据,也可以称为快照. 物化视图可 ...
- 又是一个小正则replace
var a = "http://www.xx.com?id=111&-deb"; var b = "http://www.xx.com?-deb&id=1 ...
- Web程序员开发App系列 - 申请苹果开发者账号
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- MVC 4 中编译时,让View 也弹出异常
前言 MVC在编译时,不会提示View中的错误,我们在发布项目的时候会一个一个的提示异常,项目大的时候会非常头疼,因为每次发布都需要至少5分钟,最后收到只有一个异常信息,如果页面异常过多,例如最近整理 ...
- list2json
list2json方法 System.Web.Script.Serialization.JavaScriptSerializer serial = new System.Web.Script.Seri ...