清洁的 OO 结构与.SQL性能

在PHP编程时,我总是尝试创建与数据库中的表相对应的有意义的“模型”(类)。我经常遇到以下问题:

假设我创建了一个包含两个表的数据库: 和 ,它们在我的应用程序中都有相应的模型。authorsblogs

假设我想打印所有博客以及有关作者的信息,我必须做这样的事情:

<?php
foreach ($app->getBlogs() as $blog) {
  echo "<h1>" . $blog->title . "</h1>";
  echo "Written by" . $blog->getAuthor()->name . "</p>";
  // ... et cetera
}
?>

问题是,应用程序现在将触发 1 个 SQL 查询来获取所有博客项目,并触发 [博客项目数] 查询来获取每个作者的信息。使用简单的SQL后,我可以使用简单的查询来检索此信息:

SELECT * FROM blogs
JOIN authors ON authors.id = blogs.author

处理此类问题的最佳方法是什么:开发面向对象的应用程序,而无需执行太多无用的SQL查询。


答案 1

IMO,我认为你应该写另一个类来封装你所拥有的东西。博客有作者总是有意义的吗?每个作者都有博客吗?一个作者可以有多个博客吗?考虑这些问题,然后设计一个将封装它的类。请记住,典型的数据库模式不是 OO...它们是关系性的。是的,它们很接近,但存在细微的差异。

因此,如果作者可以拥有多个博客,则可以拥有某种类型的多值类的密钥(该密钥基于作者ID),并且可以使用一个SQL调用初始化或加载此类。只是需要考虑一些事情。


答案 2

除非你知道一个事实,即低效的sql操作不会产生真正的影响,例如冗余迭代的次数或受影响的行将始终很小(例如,迭代一个系列中子级的数量,除了像Duggars这样非常罕见的情况,可以依赖小于10), 我一直更喜欢关系查询的效率,而不是OO代码的美感。

虽然丑陋的OO代码会使维护变得痛苦,但低效的数据访问可能会使系统瘫痪,通常是在您度假或试图入睡时。大多数时候,你可以找到一个很好的折衷方案,使最有效的SQL操作具有合理的“客观”接口。如果你的对象模型不漂亮,那么在重构或添加功能时,它可能会花费你更多的时间,但是每次客户按下这个按钮时,它都会花费你的时间(或者说,在更大的硬件方面,运行应用程序的钱 - 从来不是一个好的优化方法),使用应用程序所花费的工时应该远远超过开发它的工时(人们会希望)。

至于你对是否需要接口的担忧(迫使你找出所有可能的消费模式),我已经通过存储过程进行了所有数据修改来处理这个问题,但允许数据访问直接针对表和视图,只给所有用户选择权限。这是一个半有争议的立场,因为许多人希望以确保所有正在运行的sql都符合其标准的名义,锁定下游消费者的所有数据访问操作。但是,查看数据的新方法总是会出现,如果您必须添加新的存储过程,更新核心类库并在每次有人想要实现新功能时更新客户端代码,部署和资格认证可能会成为真正的负担 - 远远超过必须处理不符合宗教理想的对象模型。而且,实现代码检查过程要容易得多,该过程可以验证下游消费者编写的新选择语句是否符合犹太教标准。


推荐