简体   繁体   English

PHP、OOP 和数据库 - 性能问题

[英]PHP, OOP and Databases - performance question

I have a question regarding performance when using OOP in PHP together with databases.在 PHP 中与数据库一起使用 OOP 时,我有一个关于性能的问题。 I'll ask my question by example, suppose a class foo represents a row from some table.我将通过示例问我的问题,假设 class foo 代表某个表中的一行。 Now suppose I need to use foo at 5 different pages on my web app.现在假设我需要在我的 web 应用程序的 5 个不同页面上使用 foo。

The catch is that on each of the 5 pages I will use data from different columns.问题在于,在 5 页中的每一页上,我都将使用来自不同列的数据。 (ie the first page will use column1 and column2 while the second page uses column3 and column 4, etc..) (即第一页将使用column1 和column2,而第二页使用column3 和column 4,等等。)

The OOP approach (as far as I can see) would suggest that when I initialize foo on some particular row I would connect and fetch all the columns of that row and build my object. OOP 方法(据我所知)建议当我在某个特定行上初始化 foo 时,我将连接并获取该行的所有列并构建我的 object。 I could then proceed with my logic and use whatever data that I might need.然后我可以继续我的逻辑并使用我可能需要的任何数据。

The issue I have with this is that with the procedural approach (which I'm more used to when it comes to web) would not waste resources to download columns that I do not need since the query would be specifically tailored to the needs of the particular page.(ie If im on the first page I would only download column1 and column2 since that's what I need.)我遇到的问题是,使用程序方法(我更习惯于使用网络)不会浪费资源来下载我不需要的列,因为查询将专门针对需求而定制特定页面。(即,如果我在第一页上,我只会下载 column1 和 column2,因为那是我需要的。)

Am i going about the OOP approach wrong or is the extra overhead so insignificant that developers in general download data which they do not need?我是在谈论 OOP 方法是错误的,还是额外的开销如此微不足道,以至于开发人员通常会下载他们不需要的数据?

Thanks and sorry if this has already been covered, I thought it would be an interesting topic: :)谢谢和抱歉,如果这已经被覆盖了,我认为这将是一个有趣的话题::)

Erik埃里克

further clarification:进一步澄清:

The class is like: class 就像:

class foo
{
  $column1;
  $column2;
  $column3;
  $column4;

  public function _construct($id)
  {
    //get column 1,2,3 and 4 from database where table_id = $id
  }
}

The issue is that if i only need column1 one one page i download column2,3 and 4 for nothing.问题是,如果我只需要 column1 一页,我下载 column2,3 和 4 是免费的。 In procedural approach you would not do that.在程序方法中,您不会那样做。 Is my OOP model bad or is this ok?我的 OOP model 坏了还是这样?

I'm not entirely sure I understand your question.我不完全确定我理解你的问题。 There are three things that I think could apply to how you are approaching this problem:我认为有三件事可以适用于你如何解决这个问题:

A) You are trying to build an object and then use data contained in that object throughout your script. A) 您正在尝试构建 object,然后在整个脚本中使用 object 中包含的数据。 B) You are using a PDO style database pull. B) 您正在使用 PDO 风格的数据库拉取。 C) You are using PHPs SPL to produce an iteration over an object which contains methods to pull information from the database. C) 您正在使用 PHP SPL 对 object 进行迭代,其中包含从数据库中提取信息的方法。

I'll assume for now that you are using option A. Please forgive me if I am wrong and I am not trying to underestimate your knowledge at all...just getting it started here.我现在假设您使用的是选项 A。如果我错了,请原谅我,我并不想低估您的知识……只是从这里开始。

The approach of OOP is not to pull in all data to have it available throughout your script. OOP 的方法不是提取所有数据以使其在整个脚本中可用。 Think of it as a collection of functions instead of a collection of data, although it could easily be either or both.将其视为函数的集合而不是数据的集合,尽管它很容易成为其中之一或两者兼而有之。 You'll write your class methods just like you write functions without OOP.您将编写 class 方法,就像编写没有 OOP 的函数一样。 The only difference is, the object can be used to communicate with your script over the number of times that you need it to...唯一的区别是,object 可用于与您的脚本进行多次通信,您需要它...

To answer your question plainly, I never pull more data than I need.为了清楚地回答你的问题,我从不提取比我需要的更多的数据。 For both security and performance reasons.出于安全和性能原因。 You should use a class just like you use the procedural style.您应该像使用程序样式一样使用 class。 You could do all of your data pulls that will be required for the script upon instantiating the class (using a constructor method), but make sure that it's only the data you will need.您可以在实例化 class(使用构造函数方法)时执行脚本所需的所有数据提取,但请确保它只是您需要的数据。

----Added - - 添加

class foo{

  function getData($page){
       //Query to get the results you want based on the page number entered...
       //Process it as you normally would into a result set, array, or whatever.
       return $results;      
  }

}

Then call that然后调用

$foo = new Foo();
$page = "The page or the column that you want to pull";
$data = $foo->getData($page);

Your still doing everything procedurally, but now you have a dynamic function that can pull data based on what you send in as page... IN this case, I don't see any reason to use a constructor...only a getter method.你仍然在程序上做所有事情,但现在你有一个动态 function 可以根据你作为页面发送的内容提取数据......在这种情况下,我看不出有任何理由使用构造函数......只有一个 getter 方法.

Does that help?这有帮助吗?

You can still incorporate the selective query inside of an OOP class by using either an array of columns to grab upon construction, or by using a public class method to handle the query grabbing.您仍然可以将选择性查询合并到 OOP class 中,方法是在构造时使用要抓取的列数组,或者使用公共 class 方法来处理查询抓取。

Example of constructor:构造函数示例:

<?php

class Foo{
    public function __construct( $column ) {

        if(is_array($column)){
             if(count($column) > 1){
                 $result = mysql_query('SELECT `'.implode('`,`', $column).'` FROM `table`;');
             }else{
                 $result = mysql_query('SELECT `'.$column[0].'` FROM `table`;');
             }
        }else{
             $result = mysql_query('SELECT `'.$column.'` FROM `table`;');
        }

        $this->result = mysql_result($result, 0);
    }
}
?>

The public function method would be identical to that, except you could return the result instead of setting $this->result .公共 function 方法将与此相同,只是您可以返回结果而不是设置$this->result

The general approach will be to select only the columns you need foo->db->tablename->select('all', where date = $date) .一般的方法是 select 只需要foo->db->tablename->select('all', where date = $date)的列。 Take a quick look at frameworks such as cakephp and symfony, it might help you get a better idea of how it's generally done.快速浏览一下诸如 cakephp 和 symfony 之类的框架,它可能会帮助您更好地了解它通常是如何完成的。

My two cents.我的两分钱。 It depends on a number of things and how it affects the application as a whole ie.这取决于许多事情以及它如何影响整个应用程序,即。 # of database requests, size per record, size of rowset, etc # 数据库请求数、每条记录的大小、行集的大小等

I personally load all columns and profile to look for bottlenecks when I experience slow requests or high memory usage.当我遇到缓慢的请求或高 memory 使用率时,我个人会加载所有列和配置文件以查找瓶颈。 If I have bottlenecks then I consider lazy loading only required columns at that point.如果我遇到瓶颈,那么我会考虑延迟加载仅需要的列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM