RedBean ORM性能

Jai*_*tus 22 php orm propel doctrine redbean

我想知道,Redbean ORM可以用于社交网络应用程序等面向性能的场景,即使多个用户同时提取数千个数据,它是否也很稳定?另外我想知道Redbean是否会消耗更多的内存空间?

谁能提供Doctrine-Propel-Redbean的比较研究?

Gab*_*oij 60

我觉得Tereško的答案不太对劲.

首先,它没有解决原始问题.这确实是针对ORM的案例,我同意他的回答中描述的问题.这就是我写RedBeanPHP的原因.仅仅因为大多数ORM未能使您的生活更轻松并不意味着对象关系映射系统的概念存在缺陷.大多数ORM都试图隐藏SQL,这就是JOIN变得如此复杂的原因; 他们需要在面向对象的环境中重新发明类似的东西.这是RedBeanPHP的不同之处,因为它不会隐藏SQL.它创建易于查询的可读,有效的SQL表.RedBeanPHP使用普通的旧SQL进行记录和bean检索,而不是使用伪造的查询语言.简而言之; RedBeanPHP适用于SQL而不是它.这使得它不那么复杂.

是的,RedBeanPHP的性能很好.我怎么能这么肯定?因为与其他ORM不同,RedBeanPHP区分开发模式和生产模式.在开发周期中,数据库是流动的; 您可以添加条目,它们将动态添加.RedBeanPHP创建列,索引,猜测数据类型等.如果在一段时间后需要更多字节(更高数据类型),它甚至会拉伸列.这使得RedBeanPHP极其缓慢,但仅在开发期间速度不应成为问题.完成开发后,使用单个模式说明符R :: freeze()冻结数据库,不再进行检查.您剩下的是生产服务器上非常简单的数据库层.因为没有做太多,性能很好.

是的,我知道,我是RedBeanPHP的作者所以我有偏见.然而,我觉得我的ORM与其他ORM一样被视为同样的光,这促使我写这个.如果您想了解更多信息,请随时咨询RedBeanPHP网站,这里是关于性能讨论.

在我们公司,我们将RedBeanPHP用于嵌入式系统以及金融业务系统,因此它似乎可以很好地扩展.

我和RedBeanPHP社区一起努力使ORM世界变得更加美好; 你可以在这里阅读使命宣言.

祝您的项目顺利,希望您找到所需的技术解决方案.

  • 我刚刚放弃了doctrine2,感谢它在执行复杂查询时失败并开始尝试redbeanphp.到目前为止,我喜欢redbean的是你如何不必偏离SQL查询.我不喜欢的是它缺乏表前缀支持和命名 - 我更喜欢写表名order_detail或OrderDetail而不是orderdetail,但也许这只是我. (2认同)

ter*_*ško 35

@tereško如果可能,你可以根据你的经验给出关于纯sql的orm的优缺点,同时我也会谷歌这个话题.- Jaison Justus

嗯..用600个字符解释这个很难.

有一点我必须澄清:这是关于PHP中的ORM,虽然我很确定它也适用于一些Ruby ORM,也许还有其他.

简而言之,你应该避免它们,但是如果你必须使用ORM,那么你将更好地使用Doctrine 2.x,这是较小的邪恶.(实现类似于DataMapper而不是ActiveRecord的东西).

针对ORM的案例

一些开发人员喜欢使用ORM的主要原因也是他们最糟糕的事情:在ORM中容易做一些简单的事情,性能成本非常低.这很好.

1.指数复杂性

问题源于人们对所有事物的同一工具.如果你拥有的只是锤子(..)类型的问题.这导致产生技术债务.

首先,很容易编写新的DB相关代码.也许,因为你有一个大项目,管理在第一周(因为后来它会出现其他问题 - 阅读神话人月,如果对细节感兴趣)决定雇用更多的人.而且你最终更喜欢具有ORM技能而不是普通SQL的人.

但是,随着项目的进展,您将开始使用ORM来解决日益复杂的问题.您将开始破解一些限制,最终您可能会遇到即使使用您知道的所有ORM黑客也无法解决的问题......现在您没有SQL专家,因为您没有雇用它们.

此外,大多数流行的ORM都在实现ActiveRecord,这意味着您的应用程序的业务逻辑直接与ORM耦合.由于这种耦合,添加新功能将花费越来越多的时间.出于同样的原因,为它们编写好的单元测试是非常困难的.

2.表现

我已经提到,即使简单地使用ORM(使用单表,不使用JOIN)也会产生一些性能成本.这是因为他们使用通配符*来选择数据.如果只需要文章ID和标题列表,则无需获取内容.

当您需要基于多个条件的数据时,ORM在处理多个表时非常糟糕.考虑一下问题:

数据库包含4个表:Projects,Presentations,SlidesBulletpoints.

  • 项目有很多演讲
  • 演示文稿有很多幻灯片
  • 幻灯片有许多Bulletpoitns

你需要找到所有的内容BulletpointsSlides为"重要",从4最新的标记Presentations关系到Projects与IDS 2,4和8.

这是一个在纯SQL中编写的简单JOIN,但是在我看到的任何ORM实现中,这将导致3级嵌套循环,每个级别都有查询.


PS还有其他原因和副作用,但它们相对较小..现在还记不起任何其他重要问题.

  • ORM有利于快速发展.当您的查询很复杂时,请在纯SQL中写入.我混合两者. (5认同)
  • BTW:有关该主题的有趣文章[对象 - 关系映射是计算机科学的越南](http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-计算机science.html) (4认同)
  • @JaisonJustus,BTW我是"顺便说一句"的首字母缩写. (4认同)
  • 我明白你的观点,但我不认为这是不使用ORM的原因.正如您所说,您只需要聘请一些SQL专家,并确保在纯SQL中编写复杂的查询.ORM不会将SQL从您身边带走.问题是在哪里使用ORM以及SQL但是我相信,如果你的页面变慢,你会发现它.仍然+1为好的答案! (4认同)
  • @PhillipWhelan,嗯.. Kohana的"ORM"更像是一个美化的查询构建器,然后是ORM.当你必须提出一个复杂的请求时,你最终会以1:1的方式将纯SQL转换为kORM化的方法调用,然后将其转换回SQL.您最终只是模糊了查询,并在进程中失去了对生成的SQL的控制权. (2认同)

hal*_*fer 22

我与@tereško不同 - ORM可以使数据库查询更容易编写和更容易维护.在我看来,Propel和Doctrine有一些很棒的工作 - 利用它们!在网上有很多性能比较,并检查NotORM(我没有使用它,但如果我没记错的话,他们会对Doctrine进行一些比较).

如果达到吞吐量要求您执行原始SQL的点,那么在此时进行优化.但是,在减少错误数量和提高工作效率方面,我认为您的节​​省将为更好的服务器提供资金.当然,您的里程可能会有所不同.

顺便说一句,我不认识RedBean,但我认为Propel在大多数情况下比Doctrine更快,因为这些类是预先生成的.我使用Propel时它是唯一的选择并且坚持使用它,尽管我当然不会反对使用Doctrine.

2018年更新

经过若干年后,Propel 2仍然处于alpha状态,并且需要一些大型重构项目,遗憾的是还没有完成.虽然维护人员说这个alpha在生产中很好用,但由于它具有良好的测试覆盖率,他们现在已经开始使用Propel 3.不幸的是,在我写这篇文章时,它实际上还没有任何版本,尽管存储库是一岁.

虽然我认为Propel是一个伟大的项目,但我想知道暂时使用其他东西是否最好.它可能会从灰烬中升起!

  • 一般来说,无论您的ORM如何,您都应该警惕在内存中保留大量行.这个数字对于离线流程来说听起来不错,但对于Web请求却没有.相反,你应该分成几个部分:做20个选择每个50个元素,比如说; 这会降低内存使用率.或者,如果它是应用程序的一小部分,您可以使用原始db调用(通过ORM来维护db独立性)执行此操作.最后(还是最好的)看看你是否可以将这个东西转移到离线流程. (3认同)
  • 谷歌"推动没有梨"?大量的结果,包括我的博客:).编辑:不要花太多时间在ORM系统之间做出决定.选择一个*喜欢*并运行它.在你的系统现在零用户和你未来的Facebook大小的系统之间,你可能会重写两到三次.让它先工作. (3认同)

小智 9

我会选择"马匹为课程"的情况,利用两个世界的混合搭配.我使用RedBean构建了很少的大型应用程序,所以我的评论将完全集中在RedBean而不是其他ORM上.

是RedBean ORM慢吗?

嗯,这取决于你如何使用它.在某些情况下,它比传统查询更快,因为RedBean将结果缓存几秒钟.重用查询将更快地生成结果.使用R::debug(true);它总是显示日志

"SELECT * FROM `table` -- keep-cache"
Run Code Online (Sandbox Code Playgroud)

场景1:获取所有(*)

在RedBean中,如果您查询

$result = R::findOne('table', ' id = ?', array($id));
Run Code Online (Sandbox Code Playgroud)

这表示为

$result= mysql_query("Select * from TABLE where id =".$id);
Run Code Online (Sandbox Code Playgroud)

您可能会争辩说,如果表有多列,您应该查询(*).

场景2:单列

获取单个列

R::getCol( 'SELECT first_name FROM accounts' );
Run Code Online (Sandbox Code Playgroud)

就像我提到的"课程中的马"一样,开发人员不应该单纯依赖,FindOne, FindAll, FindFirst, FindLast而应该仔细选择他们真正需要的东西.

场景3:缓存

当您不需要缓存时,您可以在应用程序级别禁用,这不是理想的情况

R::$writer->setUseCache(true);

RedBean建议如果你不想在应用程序级别禁用缓存,你应该使用带有no-cache参数的传统查询 $result = R::exec("SELECT SQL_NO_CACHE * FROM TABLE");

这完全解决了通过完全丢弃查询缓存从表中获取实时数据的问题.

情景4:快速发展

使用ORM可以使您的应用程序开发速度非常快,开发人员可以使用ORM编写代码,比编写SQL快2-3倍.

场景5:复杂查询和关系

RedBean提供了一种实现复杂查询和/ one-to-manymany-to-many关系的非常好的方法

用于复杂查询的纯SQL

$books = R::getAll( 'SELECT 
    book.title AS title, 
    author.name AS author, 
    GROUP_CONCAT(category.name) AS categories FROM book
    JOIN author ON author.id = book.author_id
    LEFT JOIN book_category ON book_category.book_id = book.id
    LEFT JOIN category ON book_category.category_id = category.id 
    GROUP BY book.id
    ' );
    foreach( $books as $book ) {
        echo $book['title'];
        echo $book['author'];
        echo $book['categories'];
    }
Run Code Online (Sandbox Code Playgroud)

或RedBean处理多对多关系的方式

list($vase, $lamp) = R::dispense('product', 2);

$tag = R::dispense( 'tag' );
$tag->name = 'Art Deco';

//creates product_tag table!
$vase->sharedTagList[] = $tag;
$lamp->sharedTagList[] = $tag;
R::storeAll( [$vase, $lamp] );
Run Code Online (Sandbox Code Playgroud)

性能问题

像ORM这样的参数通常很慢,消耗更多内存并且往往会使应用程序变慢.我认为他们不是在谈论RedBean.

我们已经用MySQL和Postgres测试了它,相信我的性能从来都不是瓶颈.

无可否认,ORM会增加很少的开销,并且会使您的应用程序变得更慢(只是一点点).使用ORM主要是在开发人员时间和稍慢的运行时性能之间进行权衡.我的策略是首先使用ORM端到端地构建应用程序,然后基于测试用例,调整速度关键模块以使用直接数据访问.