{讨论}ORM的意义何在?

510 views
Skip to first unread message

朱涛

unread,
Jul 3, 2009, 6:17:49 AM7/3/09
to pon...@googlegroups.com
大家好,最近一直困扰我的一个问题是关于ORM(对象关系映射)的。ORM的提出是具有相当牛的意义的,它封装了底层的sql,让开发人员无需了解DB,只需要操作熟悉的类即可,可是问题来了。无论何种的封装都会给性能带来一定的损失,而作为DB应用场景很重要的一个方面即是WEB应用,其对于DB的性能要求显得尤其高。很多PV很大的网站最终的性能瓶颈都是DB的读写,那么作为在sql之上的ORM更使得性能降低不少。

ORM的已有的意义是明确的(可能不够),即
  1. 简化OO程序员的编程
  2. 便于数据库迁移
但是一个网站或者服务它对数据库迁移(如从mysql到oracle)的迁移要求有多高呢?我觉得绝大多数的应用是没有这样的需求的。
至于1的简化编程,我觉得意义也不大,因为对于一个合格的程序员来讲sql也应是其技能的一部分,即使代码看起来ugly些(很多人说raw sql写入程序中是很ugly的,我不以为然)。

到此是否可以推断ORM对于没有数据库迁移需求的合格程序员而讲是没有任何意义的呢?或者说我的理解是错误的呢?

那么ORM的意义究竟何在?欢迎大家指正和讨论。

ps 近期一个使用django(python的一种framework)的朋友每天的工作竟是将已有的ORM代码改回raw sql,我不禁想起了上面这些。
--

朱涛   Tower Joo
http://twitter.com/towerjoo
http://sites.google.com/site/towerjoo

Jeffrey Zhao

unread,
Jul 3, 2009, 6:35:05 AM7/3/09
to pon...@googlegroups.com
ORM会略为降低性能,但是降低很少,不会成为性能瓶颈。
 
Web应用的瓶颈往往在于DB查询,例如一个查询使用0.1秒,ORM耗费0.0001秒,可以忽略不计,不会“降低不少”。
 
所以说ORM会带来性能损失这句话可谓是“无稽之谈”,如果真有很多性能损失,那么应该检查ORM的方式是否有问题。
 
 
ORM的作用并不一定是数据迁移,而是在领域模型和DB Schema中进行了一次映射。
 
领域模型是一个应用中最为关键的概念,它和存储方式是无关的。
 
一个领域模型进行修改之后(这点是很常见的),而DB Schema是不用修改的,使用ORM就可以用很少的代价完成这次改变。
 
 

halida

unread,
Jul 3, 2009, 6:54:56 AM7/3/09
to TopLanguage
就俺的看法:
写程序像写文章,只写应该写的部分。
SQL的本质是获取和保存数据,即所谓的数据持久化,
我们最关心的应该是如何做业务建模,sql只是像当年的汇编一样,是ugly的选择,是面向计算机(应该是数据)的语言,能不用就不用(如果你干的就是
底层的工作那是另外一回事)。

至于效率问题,就我的看法,ORM是一个mapping,从业务逻辑mapping到sql。
作为mapping,是可以做时间和空间的均衡。比如做缓存什么的,并不像IO,CPU一样是硬件瓶颈。
俺用的是delphi,做梦都想搞一个ORM。。。可惜静态语言的ORM大多ugly,不敢用。

On Jul 3, 6:17 pm, 朱涛 <zhutao.is...@gmail.com> wrote:
> 大家好,最近一直困扰我的一个问题是关于ORM(对象关系映射)的。ORM的提出是具有相当牛的意义的,它封装了底层的sql,让开发人员无需了解DB,只需要操作熟悉的类即可,可是问题来了。无论何种的封装都会给性能带来一定的损失,而作为DB应用场景很重要的一个方面即是WEB应用,其对于DB的性能要求显得尤其高。很多PV很大的网站最终的性能瓶颈都是DB的读写,那么作为在sql之上的ORM更使得性能降低不少。
> ORM的已有的意义是明确的(可能不够),即
>

> 1. 简化OO程序员的编程
> 2. 便于数据库迁移

halida

unread,
Jul 3, 2009, 6:57:04 AM7/3/09
to TopLanguage
写完后发现,竟然和英雄的回复大致一致,幸善幸善。

On Jul 3, 6:35 pm, "Jeffrey Zhao" <je...@live.com> wrote:
> ORM会略为降低性能,但是降低很少,不会成为性能瓶颈。
>
> Web应用的瓶颈往往在于DB查询,例如一个查询使用0.1秒,ORM耗费0.0001秒,可以忽略不计,不会"降低不少"。
>
> 所以说ORM会带来性能损失这句话可谓是"无稽之谈",如果真有很多性能损失,那么应该检查ORM的方式是否有问题。
>
> ORM的作用并不一定是数据迁移,而是在领域模型和DB Schema中进行了一次映射。
>
> 领域模型是一个应用中最为关键的概念,它和存储方式是无关的。
>
> 一个领域模型进行修改之后(这点是很常见的),而DB Schema是不用修改的,使用ORM就可以用很少的代价完成这次改变。
>
> Jeffrey Zhao
> Blog:http://www.cnblogs.com/JeffreyZhao
> Twitter:http://twitter.com/jeffz_cn
>
> From: 朱涛
> Sent: Friday, July 03, 2009 6:17 PM
> To: pon...@googlegroups.com
> Subject: [TL] {讨论}ORM的意义何在?
>
> 大家好,最近一直困扰我的一个问题是关于ORM(对象关系映射)的。ORM的提出是具有相当牛的意义的,它封装了底层的sql,让开发人员无需了解DB,只需要操作熟悉的类即可,可是问题来了。无论何种的封装都会给性能带来一定的损失,而作为DB应用场景很重要的一个方面即是WEB应用,其对于DB的性能要求显得尤其高。很多PV很大的网站最终的性能瓶颈都是DB的读写,那么作为在sql之上的ORM更使得性能降低不少。
>
> ORM的已有的意义是明确的(可能不够),即

> 1.. 简化OO程序员的编程
> 2.. 便于数据库迁移

朱涛

unread,
Jul 3, 2009, 7:35:14 AM7/3/09
to pon...@googlegroups.com
我不认可jeffrey的说法,ORM的一个目标即是对各种主流的DB的支持,但显然各种DB对sql的支持情况是不同的,而且对于某个特定的DB会有更好的、更优性能的处理方式,比如mysql中一些specific sql性能是可观的,而sql server or oracle就没有对应的东西。这也就是写raw sql的好处,你可以把一个DB的性能发挥到尽量高的程度。

另外,所谓降低很少这是对一部分的封装而言的,对于更多其它的封装并非如此,比如聚合,连接等,使用raw sql可能只需要一条sql语句,而倘若使用ORM则会转换为多条sql语句。

所以,ORM
  1. 没有发挥特定DB的优势
  2. 为了为各种DB提供统一的接口,只能在特定的DB以更多的sql语句来牺牲性能
  3. ORM往往并不提供sql所有的功能,如django直到1.0还没有聚合等
希望和大家继续讨论,请指正。
2009/7/3 Jeffrey Zhao <je...@live.com>

haozes

unread,
Jul 3, 2009, 8:34:33 AM7/3/09
to pon...@googlegroups.com
ORM的缺点绝大部分是因为别拗不过SQL的劲,复杂语句,用ORM去弄,可能要麻烦.不如SQL直接了当的爽.
而不是性能低,JAVA的世界NHIBERNATE已经用的红红火火这年久,足以证明这一点

Adrienne Gusoff  - "Opportunity knocked. My doorman threw him out."

2009/7/3 朱涛 <zhutao...@gmail.com>

halida

unread,
Jul 3, 2009, 8:44:40 AM7/3/09
to TopLanguage
也就是说,
1.ORM没有满足一些DB的特性?
据我所知,有些ORM可以根据需要,对于需要性能的地方,可以用SQL实现,这样可以同时得到ORM和rawsql的好处。
2.ORM和关系数据库本质上是不相容的,无法做到完美mapping,也就无法得到最高的效率。
这个。。。感觉和当年说汇编好的人一样。。。
我想,还是根据项目来吧。根据对性能和开发效率,维护效率的角度,选择是否使用ORM.
各种工具有各种工具的好处。根据需要来选择工具吧。
不知道SQL未来会不会被取代。。从目前的角度上看,还是不能。

On Jul 3, 7:35 pm, 朱涛 <zhutao.is...@gmail.com> wrote:
> 我不认可jeffrey的说法,ORM的一个目标即是对各种主流的DB的支持,但显然各种DB对sql的支持情况是不同的,而且对于某个特定的DB会有更好的、更优性能的处理方式,比如mysql中一些specific
> sql性能是可观的,而sql server or oracle就没有对应的东西。这也就是写raw
> sql的好处,你可以把一个DB的性能发挥到尽量高的程度。
> 另外,所谓降低很少这是对一部分的封装而言的,对于更多其它的封装并非如此,比如聚合,连接等,使用raw
> sql可能只需要一条sql语句,而倘若使用ORM则会转换为多条sql语句。
>
> 所以,ORM
>

> 1. 没有发挥特定DB的优势
> 2. 为了为各种DB提供统一的接口,只能在特定的DB以更多的sql语句来牺牲性能
> 3. ORM往往并不提供sql所有的功能,如django直到1.0还没有聚合等
>
> 希望和大家继续讨论,请指正。
> --
>
> 朱涛 Tower Joohttp://twitter.com/towerjoohttp://sites.google.com/site/towerjoo


>
> 2009/7/3 Jeffrey Zhao <je...@live.com>
>
> > ORM会略为降低性能,但是降低很少,不会成为性能瓶颈。
>
> > Web应用的瓶颈往往在于DB查询,例如一个查询使用0.1秒,ORM耗费0.0001秒,可以忽略不计,不会"降低不少"。
>
> > 所以说ORM会带来性能损失这句话可谓是"无稽之谈",如果真有很多性能损失,那么应该检查ORM的方式是否有问题。
>
> > ORM的作用并不一定是数据迁移,而是在领域模型和DB Schema中进行了一次映射。
>
> > 领域模型是一个应用中最为关键的概念,它和存储方式是无关的。
>
> > 一个领域模型进行修改之后(这点是很常见的),而DB Schema是不用修改的,使用ORM就可以用很少的代价完成这次改变。
>
> > Jeffrey Zhao
> > Blog:http://www.cnblogs.com/JeffreyZhao
> > Twitter:http://twitter.com/jeffz_cn
>

> > *From:* 朱涛 <zhutao.is...@gmail.com>
> > *Sent:* Friday, July 03, 2009 6:17 PM
> > *To:* pon...@googlegroups.com
> > *Subject:* [TL] {讨论}ORM的意义何在?


>
> > 大家好,最近一直困扰我的一个问题是关于ORM(对象关系映射)的。ORM的提出是具有相当牛的意义的,它封装了底层的sql,让开发人员无需了解DB,只需要操作熟悉的类即可,可是问题来了。无论何种的封装都会给性能带来一定的损失,而作为DB应用场景很重要的一个方面即是WEB应用,其对于DB的性能要求显得尤其高。很多PV很大的网站最终的性能瓶颈都是DB的读写,那么作为在sql之上的ORM更使得性能降低不少。
>
> > ORM的已有的意义是明确的(可能不够),即
>

> > 1. 简化OO程序员的编程
> > 2. 便于数据库迁移

Jeffrey Zhao

unread,
Jul 3, 2009, 8:44:49 AM7/3/09
to pon...@googlegroups.com
我没有否认ORM对主流DB的支持,是因为你说“没有多少人会迁移”所以“ORM没大用”,而我告诉你ORM的另一个重要的作用。
 
至于不同DB的特殊写法,本来就是ORM该负责的,为同样的功能为不同的DB生成不同的SQL。
 
至于聚合连接,不知道你说的情况是什么,像Hibernate这样的ORM框架,能够生成比较漂亮的JOIN语句。
 
当然,ORM从来不是为了解决100%的问题而出现的,它只是让你用20%的实现处理80%的问题。还有20%的性能调优,自己写RAW SQL或调用存储过程即可。
 
// 选择一个ORM框架很重要,如你说的django做不到某些功能,并不是ORM不行,而是某个ORM框架不行,呵呵。

张沈鹏

unread,
Jul 3, 2009, 8:49:19 AM7/3/09
to pon...@googlegroups.com
orm只用最简单的部分
比如
http://autumn-orm.org/


复杂的还是写sql

orm的方便在于查询条件的组合

比如
a=XXX.where(xx=xxx)
if xxxx:
a=XXX.where("xxx=%s",xx)
for i in a:
....

如果拼接sql就麻烦的多
还容易有注入

qiaojie

unread,
Jul 3, 2009, 8:52:34 AM7/3/09
to pon...@googlegroups.com
ORM带来的性能问题是因为数据库和对象模型之间的本身阻抗不匹配,造成用对象模型以后无法完全映射成高效的数据库操作,更容易产生一些低效的操作。
基于数据库的应用有两类,一类是以数据库为中心,围绕数据库来做开发的应用,这类应用用ORM可能会产生性能瓶颈,还有一种只是把数据库作为持久化层,这类应用用ORM基本不会出现性能瓶颈。



2009/7/3 Jeffrey Zhao <je...@live.com>

Zoom.Quiet

unread,
Jul 3, 2009, 9:07:14 AM7/3/09
to pon...@googlegroups.com
>> From: 朱涛
>> Sent: Friday, July 03, 2009 6:17 PM
>> To: pon...@googlegroups.com
>> Subject: [TL] {讨论}ORM的意义何在?
...

>> ORM的已有的意义是明确的(可能不够),即
>>
>> 简化OO程序员的编程
>> 便于数据库迁移
>>
>> ps 近期一个使用django(python的一种framework)的朋友每天的工作竟是将已有的ORM代码改回raw
>> sql,我不禁想起了上面这些。
>> --
> 2009/7/3 Jeffrey Zhao <je...@live.com>
>>
>> ORM会略为降低性能,但是降低很少,不会成为性能瓶颈。
>>
...
>> ORM的作用并不一定是数据迁移,而是在领域模型和DB Schema中进行了一次映射。

>>
>> 一个领域模型进行修改之后(这点是很常见的),而DB Schema是不用修改的,使用ORM就可以用很少的代价完成这次改变。
>>
2009/7/3 Jeffrey Zhao <je...@live.com>:
>
> 当然,ORM从来不是为了解决100%的问题而出现的,它只是让你用20%的实现处理80%的问题。还有20%的性能调优,
...

同前所述,ORM 毕竟也是现实需求产生的,
节省直接写SQL 出错,加速80% 一般性的数据操作代码编写,
这就足够了,

如果出现频繁要手工写SQL 来完成数据提取的话,
应该质疑:
- DB 设计不合理
- 应用设计不合理

而不是质疑ORM 的作用...

想 GAE, 干脆就只给 键值形式的 BigTable ,不用"成熟","宏大"的关系DB,
一样出彩 ;-)
http://zoomquiet.org 人生苦短,Pythonic!-)
usage 7-zip to replace WinRAR/WinZip; You can get the truely Freedom 4
software.

Alan Gao

unread,
Jul 3, 2009, 7:19:15 AM7/3/09
to pon...@googlegroups.com
至于ORM的性能,我认为,ORM与RDMS相比的最大劣势是缺少数学上的完整理论。我们都知道Ralational Database是有一套完整的数学理论做基础,当设计出一套数据库后,可以通过规范化(normalization)来优化设计和提高效率。而ORM没有这样的理论,完全是看设计者的经验,这样一来,很有可以设计出效率很低的数据模型,这样的模型在RDMS跑会大大降低性能。

这里又要说说ORM的两种设计实现,一种是先有数据,再做DB Mapping, 比较典型的是Hibernate。也就是说先设计出对象类,再根据对象来映射数据库表。另一种是先设计数据库表,再做Object Mapping,典型的是iBatis。很显然,后者在DB的结构上是有保证的。这个的数据库SQL维护起来会比较方便。纯粹ORM设计出来后数据库表格有时候由于设计的原因,用SQL维护会非常吃力。

像使用iBatis这类的框架时,它比较灵活,实际上介于在ORM和RD之间的东西,即可以完成OO maping,又有raw sql的特点。只是在开发中需要额外的时间来写SQL,但相对在代码中写SQL要好很多。

ORM和RD之间的争论一直没有定论,需要根据具体项目和人个经验做取舍吧。二者皆有优劣。ORM的确可以大大简化程序的书写量,以及减少出错,对进度要求大时还是应该考虑的。

--
Alan Gao
SOFTWARE ENGINEER
-----
Java User, Ubuntu Lover, Open Source Supporter
public class LunchBox @ http://cgaolei.javaeye.com

四不象

unread,
Jul 3, 2009, 9:57:30 AM7/3/09
to pon...@googlegroups.com
性能损失事小,主要是缺乏了灵活性
----- Original Message -----
From: 朱涛
Sent: Friday, July 03, 2009 6:17 PM

Jeffrey Zhao

unread,
Jul 3, 2009, 9:58:56 AM7/3/09
to pon...@googlegroups.com
说道GAE,我不觉得它的“出彩”没有受到存储方式的影响。如果它支持RDBMS的话,再配合内置的memcached,应该会更令人欢喜。

企业系统还是离不开RDBMS的,毕竟RDBMS已经非常成熟,实践很多,而且现有项目都是构建在这上面的。

云计算要深入企业,还是逃不开RDBMS。

说到这里可能值得补充一句,理论上灵活的ORM其实不一定是O“R”M,换一个实现方式,可以变成O*M,这也是使用ORM(理论上)的好处之一吧。

--------------------------------------------------
From: "Zoom.Quiet" <zoom....@gmail.com>
Sent: Friday, July 03, 2009 9:07 PM
To: <pon...@googlegroups.com>
Subject: [TL] Re: {讨论}ORM的意义何在?

朱涛

unread,
Jul 3, 2009, 9:03:11 PM7/3/09
to pon...@googlegroups.com
看了大家的回帖,受益匪浅。个人认为,面对ORM似乎一个合理的处理方式是,如果此处有性能调优的需求,程序员就应该来写raw sql以发挥DB的高性能。那么其实这种说法一种潜在的假设是:程序员知道ORM对应的后台sql,知道生成的sql是否符合效率需求。

照此,另外的问题就随之而来:
  1. 程序员需要在同一个应用里既写ORM也要写raw sql(一方面编码的一致性问题,另一方面raw sql还是没有发挥ORM的作用,会带来移植问题)
  2. 程序员清楚地知道ORM对应的底层(map到的)sql(相比于熟练掌握sql本身,及特定于某个DB的sql,这点的难度更大,程序员需要知道ORM的底层工作机制,以及对特定DB生成的sql方式,而且仍需要sql的知识来判断所生成的sql效率是否足够,不够仍需改写为raw sql,而显然不如直接来写raw sql的简单和高效)
所以一个可行的方案理应(我的观点)是:
  • 我的应用对DB的读写性能要求不高,即有可预期的、能够支撑的读写次数,例如企业内部的信息系统等,这时直接使用ORM来简化编程过程是合适的
  • 而互联网应用,即用户数是难以提前预知的,在某一时间需要高性能的DB读写需求,并且没有更改数据库的需求,这时避开ORM统一使用raw sql比较合适
一种我个人不赞同的应用场景是,在一个应用中既写ORM,也写raw sql。

欢迎大家继续讨论,也欢迎指正。
--
2009/7/3 Jeffrey Zhao <je...@live.com>

Samuel

unread,
Jul 3, 2009, 10:13:43 PM7/3/09
to pon...@googlegroups.com
我不是很熟,一般都用ORM, 迫不得已的时候就启用sql, 因为不知道ORM要怎么做。

前天去听了一个关于数据库的讲座,不知道和这个有没有关系:
  1. raw sql有安全注入问题
  2. raw sql在数据库每次都要重新解析,而每解析一次SQL对数据库开销很大,并且RAW SQL 解析之后无法重用。 ORM解决了这个问题吗?

2009/7/4 朱涛 <zhutao...@gmail.com>



--
吴焱红 (samuel)
网易亚运频道产品组
13751821647
popo:samue...@163.com

Jeffrey Zhao

unread,
Jul 3, 2009, 11:49:47 PM7/3/09
to pon...@googlegroups.com
RAW SQL也不一定有安全注入问题——SQL再参数传递啊。
 
只要参数传递,也就是很大程度上SQL语句是复用的,会被数据库缓存。
 
ORM也是生成SQL,再通过参数传递的。
 
也就是说,就算自己使用SQL,也只是做了ORM座的事情而已。

DQP

unread,
Jul 4, 2009, 12:51:16 PM7/4/09
to TopLanguage

On 7月4日, 上午9时03分, 朱涛 <zhutao.is...@gmail.com> wrote:
> 看了大家的回帖,受益匪浅。个人认为,面对ORM似乎一个合理的处理方式是,如果此处有性能调优的需求,程序员就应该来写raw
> sql以发挥DB的高性能。那么其实这种说法一种潜在的假设是:程序员知道ORM对应的后台sql,知道生成的sql是否符合效率需求。
> 照此,另外的问题就随之而来:
>
> 1. 程序员需要在同一个应用里既写ORM也要写raw sql(一方面编码的一致性问题,另一方面raw
> sql还是没有发挥ORM的作用,会带来移植问题)
> 2. 程序员清楚地知道ORM对应的底层(map到的)sql(相比于熟练掌握sql本身,及特定于某个DB的sql,这点的难度更大,程序员需要知道ORM的底层工 作机制,以及对特定DB生成的sql方式,而且仍需要sql的知识来判断所生成的sql效率是否足够,不够仍需改写为raw

> sql,而显然不如直接来写raw sql的简单和高效)
>
> 所以一个可行的方案理应(我的观点)是:
>
> - 我的应用对DB的读写性能要求不高,即有可预期的、能够支撑的读写次数,例如企业内部的信息系统等,这时直接使用ORM来简化编程过程是合适的
> - 而互联网应用,即用户数是难以提前预知的,在某一时间需要高性能的DB读写需求,并且没有更改数据库的需求,这时避开ORM统一使用raw

> sql比较合适
>
> 一种我个人不赞同的应用场景是,在一个应用中既写ORM,也写raw sql。
>
> 欢迎大家继续讨论,也欢迎指正。

与使用RAW SQL 相对的是使用ORM框架
而不是ORM。 即使不用ORM框架 我们常常要做ORM只不过是通过写SQL来手工完成。
所以我建议把标题改为 "ORM框架的意义何在?"
ORM框架是有性能损失。 但它还是被经常使用有2点原因。
1. 虽然性能有损失 但它不是系统性能的瓶颈
2. 它太方便了 :) 损失些性能就损失吧 :p

在一个项目中有相当多的数据库操作都是十分简单的手工完成这些操作枯燥无聊而且这些操作从很少需要从SQL上进行优化(它们太简单了没有什么优化的余
地) , 就算进行优化也是在数据库上优化(比如调整索引之类)。 对于这种操作不找个框架来做那就是对自己的折磨( 我曾经受了很长时间的这种折
磨.......)

至于你说"在一个应用中既写ORM,也写raw sql" 这个我认为不对 ORM框架本来就不是用来处理所有的情况的混着用没什么不可.

我认为互联网应用的业务逻辑相对简单 而且它的性能问题是通过cache之类的方式来解决。 这点性能损失算不了什么。
(我没做过互联网应用猜测而已。。。 不对请拍砖。 谢谢)

张沈鹏

unread,
Jul 4, 2009, 1:11:38 PM7/4/09
to pon...@googlegroups.com
> 我认为互联网应用的业务逻辑相对简单  而且它的性能问题是通过cache之类的方式来解决。  这点性能损失算不了什么。

事实上
我们公司
没有用的Orm的
分歧点
主要是
有同学认为
用Orm代码风格不统一

性能没什么区别.......

张沈鹏

unread,
Jul 4, 2009, 1:25:51 PM7/4/09
to pon...@googlegroups.com
整理一下关于ORM公司讨论

---------------
张沈鹏 <zsp007> 2009年6月25日 下午10:14
Orm(或者叫DAL?)好处是不需要拼接sql
可以避免注入
用起来也很有快感

现在我正式推出震撼的整合mc,sqlstore的orm brach

分支地址

URL: https://xxx/svn//branches/zuroc/zzzorm

部分用法演示

In [12]: from luzong.autumn import Model

In [13]: class User(Model):pass
....:
init User

In [14]: for i in User.where()[:3]:print i.screen_name
....:
席殊
斯曼
旌旗

In [15]: print User.count()
163

In [16]: print User.where("id>%s",3).where("id<40").order_by("id desc").count()
0

In [17]: print User.where("id>%s",3).where("id<10000").order_by("id
desc").count()
32

In [18]: for i in User.where("id>%s",3).where("id<10000").order_by("id
desc")[:10]:print i,
....:
<__main__.User object at 0x866882c> <__main__.User object at
0x866826c> <__main__.User object at 0x86685cc> <__main__.User object
at 0x86686cc> <__main__.User object at 0x866896c> <__main__.User
object at 0x86687ac> <__main__.User object at 0x8668a2c>
<__main__.User object at 0x866878c> <__main__.User object at
0x866858c> <__main__.User object at 0x86687ec>

In [19]: User.mc.get
KeyboardInterrupt

In [19]: for i in User.where("id>%s",3).where("id<10000").order_by("id
desc")[:10]:print i.id
....:
2001
1068
1067
1066
1065
1064
1063
1062
1061
1060

In [20]: for i in User.where("id>%s",3).where("id<10000").order_by("id
desc")[:10]:print i.id
KeyboardInterrupt

In [20]: User.mc_get(2001)
Out[20]: <__main__.User object at 0x86c6a4c>

In [21]: User.mc_get_list([2001,2002])
Out[21]: [<__main__.User object at 0x86c6d8c>, None]

In [22]: User.mc_get_list([2001,1060])
Out[22]: [<__main__.User object at 0x86c672c>, <__main__.User object
at 0x86c6e8c>]

In [23]: User.mc_get_multi([2001,1060])
Out[23]:
{1060: <__main__.User object at 0x8668b2c>,
2001: <__main__.User object at 0x8668b4c>}
CJ 2009年6月26日 上午12:41
回复: xxx
收件人: xxx
再给个性能分析?
CJ


2009/6/25 张沈鹏 <zsp007>


B
回复: xxx
收件人: xxx
性能?这个就是自动做escape的字符串拼接吧, 如果一样的sql, 性能不会有差吧, 应该是没有手写sql灵活

2009/6/26 CJ <>


CJ <> 2009年6月26日 上午10:01
回复: xxx
收件人: xxx
如 User.where()[:10] 也是吗?
CJ


2009/6/26 bear tung <>


张沈鹏 <zsp007> 2009年6月26日 上午10:33
收件人: xxx
https://xxx/svn//branches/zuroc/zzzorm/luzong/autumn/db/query.py
def __getitem__(self, k):
if self.cache != None:
return self.cache[k]

if isinstance(k, (int, long)):
self.limit = (k, 1)
lst = self.get_data()
if not lst:
return None
return lst[0]
elif isinstance(k, slice):
if k.start == 0 and k.stop is None:
self.limit = ()
elif k.start is not None:
assert k.stop is not None, "Limit must be set when an
offset is present"
assert k.stop >= k.start, "Limit must be greater than
or equal to offset"
self.limit = k.start, (k.stop - k.start)
elif k.stop is not None:
self.limit = 0, k.stop

return self.get_data()
QH 2009年6月26日 上午10:44
回复: xxx
收件人: xxx
我倾向的不是一个ORM,也不是DAL,而是一个sql generator

sql和object绑定这件事情有点重,而且也和旧代码的风格有挺大差异,如果要做ORM的话,会导致代码前后风格不一致,增加维护难度。

而一个sql generator可以比较好的解决手写sql麻烦和不安全的问题(其实我并不这么觉得),比如

sql = sqlgen.select('user').where('id>%s', 3).where('id<%s',
40).order_by('id desc').count().to_sql()
cursor.execute(sql)

这样我就觉得足够了(其实和写原始sql比较起来,也差不了多少)。

这样的sql_generate的代码,可以看看web.py或者sqlalchemy,应该会有类似的实现。

2009/6/25 张沈鹏 <zsp007>:

--
QH

张沈鹏 <zsp007> 2009年6月26日 上午11:16
收件人: xxx
2009/6/26 QH:
> 我倾向的不是一个ORM,也不是DAL,而是一个sql generator


zuroc@frodo ~/dev/xxx_xss/luzong/autumn $ vi db/query.py
你说的就是这个


We can also chain the ``where`` method::

q.where(name='John').where(age=30)

In both cases the ``WHERE`` clause will become::

WHERE `name` = 'John' AND `age` = 30

You can also order using ``order_by`` to sort the results::

# The second arg is optional and will default to ``ASC``
q.order_by('column', 'DESC')

You can limit result sets by slicing the Query instance as if it were a
list. Query is smart enough to translate that into the proper ``LIMIT``
clause when the query hasn't yet been run::

q = Query(model=MyModel).where(name='John')[:10] # LIMIT 0, 10
q = Query(model=MyModel).where(name='John')[10:20] # LIMIT 10, 10
q = Query(model=MyModel).where(name='John')[0] # LIMIT 0, 1

Simple iteration::

for obj in Query(model=MyModel).where(name='John'):
# Do something here

Counting results is easy with the ``count`` method. If used on a ``Query``


> sql和object绑定这件事情有点重,而且也和旧代码的风格有挺大差异,如果要做ORM的话,会导致代码前后风格不一致,增加维护难度。

我到不觉得难懂
正如mako和ptl并存
没有人觉得mako难懂

QH 2009年6月26日 上午11:23
回复: xxx
收件人: xxx
2009/6/26 张沈鹏 <zsp007>:
> 2009/6/26 QH:
>> 我倾向的不是一个ORM,也不是DAL,而是一个sql generator
>
>
> zuroc@frodo ~/dev/xxx_xss/luzong/autumn $ vi db/query.py
> 你说的就是这个
>
>
> We can also chain the ``where`` method::
>
> q.where(name='John').where(age=30)
>
> In both cases the ``WHERE`` clause will become::
>
> WHERE `name` = 'John' AND `age` = 30
>
> You can also order using ``order_by`` to sort the results::
>
> # The second arg is optional and will default to ``ASC``
> q.order_by('column', 'DESC')
>
> You can limit result sets by slicing the Query instance as if it were a
> list. Query is smart enough to translate that into the proper ``LIMIT``
> clause when the query hasn't yet been run::
>
> q = Query(model=MyModel).where(name='John')[:10] # LIMIT 0, 10
> q = Query(model=MyModel).where(name='John')[10:20] # LIMIT 10, 10
> q = Query(model=MyModel).where(name='John')[0] # LIMIT 0, 1
>
> Simple iteration::
>
> for obj in Query(model=MyModel).where(name='John'):
> # Do something here
>
> Counting results is easy with the ``count`` method. If used on a ``Query``

看起来似乎就是这个。如果有人喜欢用这样的库去生成sql,我没有意见,虽然我自己还是会直接写sql,但是至少我很容易理解别人的代码究竟干了些什么。

>> sql和object绑定这件事情有点重,而且也和旧代码的风格有挺大差异,如果要做ORM的话,会导致代码前后风格不一致,增加维护难度。
>
> 我到不觉得难懂
> 正如mako和ptl并存
> 没有人觉得mako难懂

我也没有说mako难懂。我是说一个项目里又有mako又有ptl难维护。我不止一次的干过为了改某个页面元素要到ptl里去改一遍,再到mako里去改一遍的事情。

--

张沈鹏 <zsp007> 2009年6月26日 上午11:28
收件人: xxx
> 看起来似乎就是这个。如果有人喜欢用这样的库去生成sql,我没有意见,虽然我自己还是会直接写sql,但是至少我很容易理解别人的代码究竟干了些什么。
orm 主要是修改起来方便

user = User.get(1324)
user.name = name
user.age =age
user.save()

User(name="xxxx",age="xxx").save()

User.where(age=10).update(name="xxxx")

这样写起来比写sql方便很多
QH 2009年6月26日 上午11:32
回复: xxx
收件人: xxx
2009/6/26 张沈鹏 <zsp007>:

是方便,但只方便一点点。用sql就是这样两条语句

update user set name='xxxx', age='xxx' where id=1324;
update user set name='xxxx' where age=10;

张沈鹏 <zsp007> 2009年6月26日 下午12:24
收件人: xxx
>> User.where(age=10).update(name="xxxx")
>>
>> 这样写起来比写sql方便很多
>
> 是方便,但只方便一点点。用sql就是这样两条语句


User.where(age=age).update(name=name)

VS
cursor = store.get_cursor(table="user")
cursor.execute("update user set name=%s where age=%s",name,age)
cursor.connection.commit()

>
> update user set name='xxxx', age='xxx' where id=1324;
> update user set name='xxxx' where age=10;
>
> --
> QH

>

--

张沈鹏 <zsp007> 2009年6月26日 下午1:07
收件人: xxx
def register_subject_image(subject_id, label, user_id, x, y, filesize):
cursor = store.get_cursor()

cursor.execute('select id, x, y, filesize from subject_image where
subject_id=%s', (subject_id, ))

for r in cursor.fetchall():
if -2 < filesize-r[3] < 2 and x == r[1] and y == r[2]:
return r[0]
cursor.execute("insert into subject_image
(subject_id,user_id,label,x,y,filesize) values (%s,%s,%s,%s,%s,%s)",
(subject_id, user_id, label, x, y, filesize))
pid = cursor.lastrowid
if pid:
cursor.connection.commit()
return pid
else:
cursor.connection.rollback()

def register_subject_image(subject_id, label, user_id, x, y, filesize):
for img in SubjectImage.where(subject_id)
if img and abs(img.filesize-filesize)<2 and x == img.x and y == img.y:
return img.id

img = SubjectImage()
img.subject_id = subject_id
img.user_id=user_id
img.label=label
img.x=x
img.y=y
#也可以这么写 img =
SubjectImage(x=x,y=y,label=label,user_id=user,subject_id=subject)
img.save()
return img.id

我不清楚原来这里为什么要rollback,但如果要rollback可以这样写
img.begin()
try:
img.save()
img.commit()
except:
img.rollback()
张沈鹏 <zsp007> 2009年6月26日 下午1:07
收件人: xxx
哦 上面是举一个例子
张沈鹏 <zsp007> 2009年6月26日 下午1:09
收件人: xxx
for img in SubjectImage.where(subject_id)
这一句应该是
for img in SubjectImage.where(subject_id=subject_id)
QH 2009年6月26日 下午1:28
回复: xxx
收件人: xxx

2009/6/26 张沈鹏 <zsp007>:
> User.where(age=age).update(name=name)

难道你这里就直接commit了?要做trasaction怎么办?

如果想auto commit的话,封装一个函数就行:

store.commit_sql("update user set name=%s where age=%s", (name, age),
table='user')

def commit_sql(self, sql, paras=(), table=None):
if table is None:
table = find_table_from_sql(sql)
cursor = self.get_cursor(table=table)
cursor.execute(sql, paras)
cursor.commit()

> VS
> cursor = store.get_cursor(table="user")
> cursor.execute("update user set name=%s where age=%s",name,age)
> cursor.connection.commit()


--

张沈鹏 <zsp007> 2009年6月26日 下午1:38
收件人: xxx
2009/6/26 QH:
>
> 2009/6/26 张沈鹏 <zsp007>:
>> User.where(age=age).update(name=name)
>
> 难道你这里就直接commit了?要做trasaction怎么办?

见上面的那个例子

> 如果想auto commit的话,封装一个函数就行:
>
> store.commit_sql("update user set name=%s where age=%s", (name, age),
> table='user')
>
> def commit_sql(self, sql, paras=(), table=None):
> if table is None:
> table = find_table_from_sql(sql)
> cursor = self.get_cursor(table=table)
> cursor.execute(sql, paras)
> cursor.commit()
>
>> VS
>> cursor = store.get_cursor(table="user")
>> cursor.execute("update user set name=%s where age=%s",name,age)
>> cursor.connection.commit()
>
>
>
>
> --
> QH
>
> --~--~---------~--~----~------------~-------~--~----~
> 您收到此信息是由于您订阅了 Google 论坛“xxx-dev”论坛。
> 要在此论坛发帖,请发电子邮件到 xxx
> 要退订此论坛,请发邮件至 xxx-dev+u...@googlegroups.com
> 更多选项,请通过 http://groups.google.com/group/xxx-dev?hl=zh-CN 访问该论坛
> -~----------~----~----~----~------~----~------~--~---
>
>


bear tung <> 2009年6月26日 下午1:45
回复: xxx
收件人: xxx
不赞成auto commit, commit应该都是显式调用的

2009/6/26 QH


2009/6/26 张沈鹏 <zsp007>:
> User.where(age=age).update(name=name)

难道你这里就直接commit了?要做trasaction怎么办?

如果想auto commit的话,封装一个函数就行:

store.commit_sql("update user set name=%s where age=%s", (name, age),
table='user')

def commit_sql(self, sql, paras=(), table=None):
if table is None:
table = find_table_from_sql(sql)
cursor = self.get_cursor(table=table)
cursor.execute(sql, paras)
cursor.commit()

> VS
> cursor = store.get_cursor(table="user")
> cursor.execute("update user set name=%s where age=%s",name,age)
> cursor.connection.commit()


--
QH


--~--~---------~--~----~------------~-------~--~----~

QH 2009年6月26日 下午1:55
回复: xxx
收件人: xxx
那你上一封信就应该变成

x = User.where(age=age)
x.begin()
x.update(name=name)
x.commit()

VS

cursor = store.get_cursor(table="user")
cursor.execute("update user set name=%s where age=%s",name,age)
cursor.connection.commit()

复杂度还是相差不大

而且,如果是跨表的transaction怎么办?


2009/6/26 张沈鹏 <zsp007>:
> 2009/6/26 QH:
>>
>> 2009/6/26 张沈鹏 <zsp007>:
>>> User.where(age=age).update(name=name)
>>
>> 难道你这里就直接commit了?要做trasaction怎么办?
>
> 见上面的那个例子
>
>> 如果想auto commit的话,封装一个函数就行:
>>
>> store.commit_sql("update user set name=%s where age=%s", (name, age),
>> table='user')
>>
>> def commit_sql(self, sql, paras=(), table=None):
>> if table is None:
>> table = find_table_from_sql(sql)
>> cursor = self.get_cursor(table=table)
>> cursor.execute(sql, paras)
>> cursor.commit()
>>
>>> VS
>>> cursor = store.get_cursor(table="user")
>>> cursor.execute("update user set name=%s where age=%s",name,age)
>>> cursor.connection.commit()
>>
>>
>>
>>
>> --
>> QH
>>
>> >
>>
>
>
>
> --
> 弓长
> 孝文
> 、
> 王
> http://zsp.javaeye.com/
>
> >
>

--

张沈鹏 <zsp007> 2009年6月26日 下午2:38
收件人: xxx
2009/6/26 QH:
> 那你上一封信就应该变成
>
> x = User.where(age=age)
> x.begin()
> x.update(name=name)
> x.commit()

默认是auto commit
我喜欢auto commit

> VS
>
> cursor = store.get_cursor(table="user")
> cursor.execute("update user set name=%s where age=%s",name,age)
> cursor.connection.commit()
>
> 复杂度还是相差不大
>
> 而且,如果是跨表的transaction怎么办?
对一个begin,commit就可以了

--

QH 2009年6月26日 下午2:47
回复: xxx
收件人: xxx
2009/6/26 张沈鹏 <zsp007>:
> 2009/6/26 QH:
>> 那你上一封信就应该变成
>>
>> x = User.where(age=age)
>> x.begin()
>> x.update(name=name)
>> x.commit()
>
> 默认是auto commit
> 我喜欢auto commit

auto commit 的情况见我上一封信。直接用sql仅仅是一个函数封装的问题。

>> VS
>>
>> cursor = store.get_cursor(table="user")
>> cursor.execute("update user set name=%s where age=%s",name,age)
>> cursor.connection.commit()
>>
>> 复杂度还是相差不大
>>
>> 而且,如果是跨表的transaction怎么办?
> 对一个begin,commit就可以了

举个例子?


--

张沈鹏 <zsp007> 2009年6月26日 下午3:06
收件人: xxx
1.innodb事务是自动开启
所以只需要不提交就是一个事物

2.同一个数据库中的表的begin是同样的作用

db = new_class.db = sqlstore.get_farm_by_table(new_class.Meta.table)
...........

@classmethod
def begin(cls):
"""
begin() and commit() let you explicitly specify an SQL transaction.
Be sure to call commit() after you call begin().
"""
db = cls.db
db.b_commit = False

@classmethod
def commit(cls):
db = cls.db
try:
cursor = db.get_cursor()
cursor.connection.commit()
finally:
db.b_commit = True

@classmethod
def rollback(cls,db=None):
db = cls.db
try:
cursor = db.get_cursor()
cursor.connection.rollback()
finally:
db.b_commit = True
QH 2009年6月26日 下午3:20
回复: xxx
收件人: xxx

举个例子吧:

两张表,user和location_stats。一个transaction:
把id为12345的user的location设置成'beijing',并把id为'beijing'的location_stats的user_count列加一。

直接用sql就是这样:

c = store.get_cursor(tables=['user', 'location_stats'])
c.execute("update user set location=%s where id=%s", ('beijing', 12345))
c.execute("update location_stats set user_count=user_count+1 where
id=%s", 'beijing')
c.connection.commit()

ORM呢?

2009/6/26 张沈鹏 <zsp007>:
>


张沈鹏 <zsp007> 2009年6月26日 下午3:26
收件人: xxx
User.begin()
User.where(id=1345).update(location="beijing")
LocationStats.where(id="beijing").update("user_count=user_count+1")
User.commit()

--

张沈鹏 <zsp007> 2009年6月26日 下午3:35
收件人: xxx
update 的参数是这样拼出来的

def update(self,*args,**kwds):
values = self.extract_condition_values()
update_set=[]
if args:
update_set.append(args[0])
values=args[1:]+values
if kwds:
update_set.append(
','.join(
"%s=%%s"%(
escape(k)
)
for k in kwds.keys()
)
)
values = list(kwds.values())+values
if update_set:
Query.raw_sql(
'UPDATE %s SET %s %s' % (
self.model.Meta.table_safe,
','.join(update_set),
self.extract_condition_keys() or ''
),
values,
self.db
)

也就是可以写

update("sss=xxx")

update("sss=%s",xxx)

update(ss=xxx)

update("sss=%s",xxx,xxx,xxxx=xxx)
张沈鹏 <zsp007> 2009年6月26日 下午3:45
收件人: xxx
本orm另外一大好处是集成了memcache
可以方便的mc_get_list([id_1,id_2]),mc_get_mulit([id_1,id_2]),mc_get(id)
并可以通过设置Meta中的mc_key,mc_ver来更换mc
mc_key默认是 表名@版本号:%s

# Assume id is the default
if not getattr(new_class.Meta, 'pk', None):
new_class.Meta.pk = 'id'
if not getattr(new_class.Meta,'mc_key',None):
mc_ver = getattr(new_class.Meta,"mc_ver","")
new_class.Meta.mc_key = "%s@%s:%%s"%(name,mc_ver)
QH 2009年6月26日 下午4:23
回复: xxx
收件人: xxx
2009/6/26 张沈鹏 <zsp007>:
> User.begin()
> User.where(id=1345).update(location="beijing")
> LocationStats.where(id="beijing").update("user_count=user_count+1")
> User.commit()
>
>> c = store.get_cursor(tables=['user', 'location_stats'])
>> c.execute("update user set location=%s where id=%s", ('beijing', 12345))
>> c.execute("update location_stats set user_count=user_count+1 where
>> id=%s", 'beijing')
>> c.connection.commit()

看起来和直接写sql的复杂度还是差不多。从代码上看不出来LocationStats和User是在同一个transaction内,个人感觉还不如sql代码来得直观。
另外,这里也没有判断LocationStats和User是否在同一个mysql server上的检查。

到目前为止,ORM还没有足够的好处驱动我迁移。我觉得一个sql generator加稍许常用调用pattern的封装足矣。

其他人的意见?

--

张沈鹏 <zsp007> 2009年6月26日 下午4:29
收件人: xxx
cursor.execute("insert into deleted_note_photo "
"(`id`,seq_id,note_id,author_id,title,layout,album_id,"
"album_photo_id,`time`,delete_user_id,flag)"
" values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
(p.id, p.seq_id, p.note_id, p.author_id, p.title,
p.layout, p.album_id, p.album_photo_id,
p.creation_date, user.id, self.domain))


比起这样的代码
用orm显然好看的多
flycondor <flycondor> 2009年6月26日 下午4:32
回复: xxx
收件人: xxx
如果我们在数据库访问层遵循类似friendfeed的schemaless那样很简单的范式
那么orm价值比较大

在此之前,差别不大
基本上是学习路径决定个人喜好

2009/6/26 QH

2009/6/26 张沈鹏 <zsp007>:


张沈鹏 <zsp007> 2009年6月26日 下午4:34
收件人: xxx
在比如这样的代码 就是手工写了一个orm

sql ="""select `id`, seq_id, note_id, author_id, flag, title,
album_id, album_photo_id,
`time` from note_photo order by `id` desc limit %d, %d""" %
(start, start+limit)
cursor.execute(sql)
rs = cursor.fetchall()
ps = [NotePhoto(r[0],r[1],r[2],r[3],r[4],r[5],None,r[6],r[7],r[8])
for r in rs]
张沈鹏 <zsp007> 2009年6月26日 下午4:40
收件人: xxx
2009/6/26 flycondor <F>:
> 如果我们在数据库访问层遵循类似friendfeed的schemaless那样很简单的范式
> 那么orm价值比较大

可以在新的项目中试试


QH 2009年6月29日 上午11:06
回复: xxx
收件人: xxx
2009/6/26 flycondor <flycondor>:
> 如果我们在数据库访问层遵循类似friendfeed的schemaless那样很简单的范式
> 那么orm价值比较大

即使在那种情况下,我也会建议把ORM和DAL分离开来。DAL是必须的,ORM是可选的。ORM构建在DAL之上。

> 在此之前,差别不大
> 基本上是学习路径决定个人喜好

这不是喜好的问题。我自己的个人项目里经常会使用ORM来定义数据结构,因为ORM更适合从程序员的角度考虑问题,而不是从数据存储的角度考虑问题。

我反对在代码中引入ORM的最主要理由是代码维护难度。从mako和权限框架两次重构经验我们看到,一旦代码中同时出现两种风格,会使得代码整体的易读性和可维护性变低,学习成本也会大大提高。因此除了能够带来明显的好处以外(mako和权限框架我认为是属于有明显好处的例子),我不赞成在代码中再次引入新风格。要么把所有代码都重构成新风格,要么能够说服所有开发者愿意接受在有两种风格的code
base上进行开发。这也是为什么上次石头讨论前端代码重构时我强调这件事情要么不做,要么就要做完的原因。

朱涛

unread,
Jul 5, 2009, 9:25:44 AM7/5/09
to pon...@googlegroups.com
@张沈鹏 谢谢教主的回答, 从你的mail来看,你是更赞同只在sql上薄薄地封装一层(?), 不失sql的灵活性,也不至于raw sql那般的 "ugly".

@DQP 谢谢你的指正, 在不至误解的前提下, 我觉得大家都是清楚我的意思的.

@Jeffrey 你说的是有道理的, raw sql和ORM实际是做着相同的事, 但是相对而言, raw sql更加底层, 也就是说ORM最终还是要转换为raw sql向db提出请求.


但是, 从我个人的角度来看, 在性能很critical的情况下,raw sql是更合适的.

另外, 我也在stackoverflow上发了相同的问题, 大家也可以参考: http://stackoverflow.com/questions/1083736/whats-the-meaning-of-orm

大致总结下在SO上回答的帖子的观点:
  1. 坚持使用ORM直至发现有性能的瓶颈,然后解决之(这个回答可能很符合 提前优化是万恶之源的说法, 但是当你后期再优化时, 有没有想着为什么自己当初不直接使用raw sql?)
  2. 性能更多是DB设计层面的而不是ORM本身(这点我基本同意,但是如果在相同DB设计的基础上,同样存在本帖提到的问题)
  3. 更多需要的是在大的层面的优化,而不是每条语句都需要优化,所以ORM可以让你focus到一定的高度,而不是陷入局部优化的trap(这点让我豁然开朗)
  4. 当然也有和我的想法相同的,也就是说当你没有数据库迁移的需求时,你大可不必使用ORM, stick to raw sql

欢迎大家继续讨论.请有实际相关经验的朋友能够也谈下自己的经验, 谢谢.
2009/7/5 张沈鹏 <zsp007@gmail.com>

张沈鹏

unread,
Jul 5, 2009, 9:38:17 AM7/5/09
to pon...@googlegroups.com
2009/7/5 朱涛 <zhutao...@gmail.com>:

> @张沈鹏 谢谢教主的回答, 从你的mail来看,你是更赞同只在sql上薄薄地封装一层(?), 不失sql的灵活性,也不至于raw sql那般的
> "ugly".

是只要一层

另外就是

类似friendfeed那种用法
用orm比较方便

@@

unread,
Jul 5, 2009, 9:58:08 AM7/5/09
to pon...@googlegroups.com


2009/7/5 朱涛 <zhutao...@gmail.com>

但是, 从我个人的角度来看, 在性能很critical的情况下,raw sql是更合适的.

这个是和你数据库最终大小有关系的。
数据库大了 你会发现你没法去做join之类的操作 raw sql和orm的sql一样,都不满足

所以gae才会有这样的设计 ,gae的datastore设计的一个出发点就是 无论数据有多大查询的速度不变。
因此count aggregation join之类的操作都是没有的,因为到你数据量足够大的时候就算是在支持这些操作的RDBMS上做这些操作也会因为太慢而几乎等同于不可用。

跑题了,上面说的就是数据库大的时候你的查询又会回到简单查询,这样的话ORM就足够了

另外ORM和raw sql混和难看不难看还得看代码的组织吧 呵呵

Linker

unread,
Jul 8, 2009, 1:34:04 PM7/8/09
to pon...@googlegroups.com
最大的意义是sql数据库可以继续卖钱!

On 7/3/09, 朱涛 <zhutao...@gmail.com> wrote:
> 大家好,最近一直困扰我的一个问题是关于ORM(对象关系映射)的。ORM的提出是具有相当牛的意义的,它封装了底层的sql,让开发人员无需了解DB,只需要操作熟悉的类即可,可是问题来了。无论何种的封装都会给性能带来一定的损失,而作为DB应用场景很重要的一个方面即是WEB应用,其对于DB的性能要求显得尤其高。很多PV很大的网站最终的性能瓶颈都是DB的读写,那么作为在sql之上的ORM更使得性能降低不少。
> ORM的已有的意义是明确的(可能不够),即
>

> 1. 简化OO程序员的编程
> 2. 便于数据库迁移


>
> 但是一个网站或者服务它对数据库迁移(如从mysql到oracle)的迁移要求有多高呢?我觉得绝大多数的应用是没有这样的需求的。
> 至于1的简化编程,我觉得意义也不大,因为对于一个合格的程序员来讲sql也应是其技能的一部分,即使代码看起来ugly些(很多人说raw
> sql写入程序中是很ugly的,我不以为然)。
>
> 到此是否可以推断ORM对于没有数据库迁移需求的合格程序员而讲是没有任何意义的呢?或者说我的理解是错误的呢?
>
> 那么ORM的意义究竟何在?欢迎大家指正和讨论。
>
> ps 近期一个使用django(python的一种framework)的朋友每天的工作竟是将已有的ORM代码改回raw sql,我不禁想起了上面这些。
> --
>
> 朱涛 Tower Joo
> http://twitter.com/towerjoo
> http://sites.google.com/site/towerjoo
>

--
Sent from my mobile device

Regards,
Linker Lin
linker...@gmail.com

free.wang

unread,
Jul 8, 2009, 4:01:26 PM7/8/09
to pon...@googlegroups.com
看到这个讨论 我突然想到想到的是ORM 面对复杂SQL的乏力。
其次我就想到了MYSQL 的问题  个人比较怀疑ORACLE  所以决定转POSTGRESQL了 
一直听说他的多表性能比MYSQl强  不知道事实如何
不知不觉就把这2个扯在一起了

2009/7/9 Linker <linker...@gmail.com>



--
真正的杰出,不是妙用规则的错层,而是极致的偏执于信念.
The Crankiness of  Belief achieves Great , not the Trick of Regulation.

Jeffrey Zhao

unread,
Jul 8, 2009, 9:16:48 PM7/8/09
to pon...@googlegroups.com
一个项目又有多少复杂SQL,使用ORM也没有阻止这个项目使用RAW SQL。
 
怀疑Oracle的什么呢?Oracle,SQL Server这样的商业RDBMS的性能和功能,都不是MySQL,PostgreSQL这样的开源数据库可以比拟的——价格除外。

From: free.wang
Sent: Thursday, July 09, 2009 4:01 AM
Subject: [TL] Re: {讨论}ORM的意义何在?

wing

unread,
Jul 8, 2009, 9:55:18 PM7/8/09
to pon...@googlegroups.com
同感,你有多少复杂的sql,20%很多吧,使用orm一样可以很方便的使用raw sql,orm带来的便利只要用过都知道,但是非要一条条列出来,
就挺头痛,写这种话题,就象给不懂技术的领导写报告,说某项新技术能带来什么好处一样痛苦,我不相信用orm做过几个项目的,会感受
不到带来开发效率的提升?好处显然是不言而喻,当然如果你的库表没几个字段,一共也没几张表,也许带来的便利不足以让你引入orm,那
只是适用项目的问题。。。

2009/7/9 Jeffrey Zhao <je...@live.com>:


> 一个项目又有多少复杂SQL,使用ORM也没有阻止这个项目使用RAW SQL。
>
> 怀疑Oracle的什么呢?Oracle,SQL

> Server这样的商业RDBMS的性能和功能,都不是MySQL,PostgreSQL这样的开源数据库可以比拟的----价格除外。

--
wing
wing9...@gmail.com
Hope is a good thing, maybe the best of things.

Reply all
Reply to author
Forward
0 new messages