21

我想知道,Redbean ORM能不能用在社交网络应用这种面向性能的场景中,多用户同时拉取上千条数据是否稳定?另外我想知道Redbean是否消耗更多的内存空间?

谁能提供教义-推进-红豆的比较研究?

4

4 回答 4

65

我觉得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 世界变得更美好;你可以在这里阅读使命宣言。

祝你的项目好运,我希望你能找到你正在寻找的技术解决方案。

于 2011-11-21T23:35:03.027 回答
37

@tereško 如果可能的话,您能否根据您的经验给出 orm 相对于纯 sql 的优缺点,我也会同时搜索该主题。——杰森·贾斯图斯

嗯.. 用 600 个字符来解释这一点很难。

我必须澄清一件事:这是关于PHP中的 ORM ,尽管我很确定它也适用于一些 Ruby ORM,也许还有其他。

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

针对 ORM 的案例

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

1. 指数复杂度

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

一开始很容易编写新的数据库相关代码。也许,因为你有一个大项目,第一周的管理层(因为以后会出现其他问题 - 如果对细节感兴趣,请阅读The Mythical Man-Month决定雇用更多人。你最终会更喜欢具有 ORM 技能的人,而不是一般的 SQL。

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

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

2. 性能

我已经提到,即使是简单的 ORM 使用(使用单表,否JOIN)也会有一些性能成本。这是因为他们使用通配符*来选择数据。当您只需要文章 ID 和标题列表时,获取内容是没有意义的。

当您需要基于多个条件的数据时,ORM 非常不适合处理多个表。考虑问题:

数据库包含 4 个表:ProjectsPresentations和。SlidesBulletpoints

  • 项目有很多演示
  • 演示文稿有很多幻灯片
  • 幻灯片有很多要点

并且您需要从与 ID 为 2、4 和 8的 4 个最新相关BulletpointsSlides标记为“重要”的所有内容中查找内容。PresentationsProjects

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


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

于 2011-10-14T12:05:02.757 回答
22

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

如果您达到吞吐量要求您执行原始 SQL 的程度,则在该点进行优化。但是在减少错误数量和提高生产力方面,我认为您的储蓄无论如何都会为更好的服务器提供资金。当然,您的里程可能会有所不同。

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

2018 年更新

多年后,Propel 2 仍处于 alpha 阶段,需要一些大型重构项目,遗憾的是这些项目都没有完成。尽管维护人员说这个 alpha 版在生产环境中使用得很好,因为它有很好的测试覆盖率,他们现在已经开始使用 Propel 3。不幸的是,在我写这篇文章的时候,它实际上还没有任何版本,尽管存储库已经一岁了。

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

于 2011-10-14T09:41:33.103 回答
10

我会选择“Horses for Courses”的情况,它利用了两个世界的混合和匹配。我已经使用 RedBean 构建了一些大型应用程序,因此我的评论将仅关注 RedBean 而不是其他 ORM。

RedBean ORM 慢吗?

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

"SELECT * FROM `table` -- keep-cache"

场景 1:获取所有 (*)

在 RedBean 中,如果您查询

$result = R::findOne('table', ' id = ?', array($id));

这表示为

$result= mysql_query("Select * from TABLE where id =".$id);

您可能会争辩说,如果表有多个列,为什么要查询(*)

场景 2:单列

获取单个列

R::getCol( 'SELECT first_name FROM accounts' );

就像我提到的“课程用马”,开发人员不应该简单地依赖FindOne, FindAll, FindFirst, FindLast而是仔细起草他们真正需要的东西。

场景 3:缓存

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

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

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

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

场景四:快速发展

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

场景 5:复杂的查询和关系

RedBean 提供了一种非常好的实现复杂查询和one-to-many/或many-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'];
    }

或 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] );

性能问题

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

我们已经使用 MySQL 和 Postgres 对其进行了测试,相信我的性能从来都不是瓶颈。

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

于 2016-06-13T11:24:25.133 回答