1

我希望标题足够描述性,我不知道如何命名。

假设我有以下代码:

Class Movie_model {

    public method getMoviesByDate($date) {
        // Connects to db
        // Gets movie IDs from a specific date
        // Loop through movie IDs
        // On each ID, call getMovieById() and store the result in an array
        // When all IDs has looped, return array with movies returned from getMovieById().
    }

    public function getMovieById($id) {
         // Get movie by specified ID
         // Also get movie genres from another method
         // Oh, and it gets movie from another method as well.
    }

}

获取电影时,我总是希望得到相同的结果(我总是希望 getMovieById() 的结果。

我希望你明白我的意思。我将拥有许多其他函数,例如 getMoviesByDate(),例如,我还将拥有 getMoviesByGenre(),并且我希望它也返回与 getMovieById() 相同的电影信息。

这样做“可以”吗?我知道这会给服务器带来更多负载并增加加载时间,但是还有其他更好的方法我不知道吗?

编辑:我稍微澄清了 getMoviesByDate() 中的代码。此外,getMovieByDate() 只是一个示例。正如我所说,我还将调用 getMoviesByGenre() 之类的方法。

编辑:我目前在项目的首页上运行 48 个数据库查询,而首页还远未完成,所以当我完成时,这个数字至少会增加三倍。几乎所有查询都需要大约 0.0002,但随着数据库的不断增长,我猜这个数字会急剧上升。我需要改变一些东西。

4

4 回答 4

1

在一个类上拥有getMoviesByDate()getMoviesById()方法似乎不太合乎逻辑。Movie

另一种方法是使用某种MovieManager类来完成所有检索并返回Movie对象。

class MovieManager {

    public function getMoviesByDate($date) {
        // get movies by date, build an array of Movie objects and return
    }

    public function getMoviesByGenre($genre) {
       // get movies by genre, build an array of Movie objects and return
    }

    public function getMovieById($id) {
       // get movie by id, return Movie object
    }

}

您的Movie类将仅具有特定于单个电影的属性和方法:

class Movie {

    public id;
    public name;
    public releaseDate;

}

可以有单独的方法来获取日期、流派等,但您必须确保您不会多次调用相同的记录 - 在这种情况下,您将需要一个可以连接您需要的各种表的单个查询。

编辑 - 在你澄清你的问题之后:

按日期获取电影 ID,然后将它们全部运行的想法getMovieById()很糟糕!按日期获取时应该拉取电影数据,因此您不必再次访问数据库。

于 2012-10-11T06:55:37.937 回答
1

我认为在这种特殊情况下这样工作并不好。函数 getMoviesByDate 将从单个查询中返回一定数量的“n”部电影(或电影 ID)。对于此查询中的每个 id,您将有一个单独的查询来通过指定的 ID 获取电影。

这意味着如果第一个函数将返回 200 部电影,您将运行 getMovieById() 函数(以及其中的查询)200 次。更好的做法 (IMO) 是在 getMoviesByDate() 函数中获取您需要的所有信息并将其作为集合返回。

于 2012-10-11T06:43:19.190 回答
0

您可以修改您的getMovieById函数。您可以将日期作为参数传递,该函数应按电影 ID 返回电影并按日期过滤。

于 2012-10-11T06:49:31.160 回答
-1

要跟踪您之前已加载到 RAM 中的记录,您可以为模型使用基类,该基类保存已加载记录的 id 以及对 RAM 中模型对象的对象的引用。

class ModelBase {
    /* contains the id of the current record, null if new record */
    protected $id;

    // keep track of records already loaded
    static $loaded_records = Array();

    public function __construct(Array $attr_values) {
        // assign $attr_values to this classes attributes

        // save this instance in class variable to reuse this object
        if($attr_values['id'] != null) {
            self::$loaded_records[get_called_class()][$attr_values['id']] = $this;
        }
    }

    public static function getConcurrentInstance(Array $attr_values) {

        $called_class = get_called_class();
        if(isset(self::$loaded_records[$called_class][$attr_values['id']])) {

            // this record was already loaded into RAM
            $record = self::$loaded_records[$called_class][$attr_values['id']];

            // you may need to update certain fields of $record
            // from the data in $attr_values, because the data in the RAM may
            // be old data.

        } else {
            // create the model with the given values
            $record = new $called_class($attr_values);
        }
        return $record;
    }

    // provides basic methods to update records in ram to database etc.
    public function save() {
        // create query to save this record to database ...
    }
}

您的电影模型可能看起来像这样。

Class MovieModel extends ModelBase {
    // additional attributes
    protected $title;
    protected $date;
    // more attributes ...


    public static function getMoviesByDate($date) {
       // fetches records from database
       // calls getConcurrentInstance() to return an instance of MovieModel() for every record
    }

    public static function getMovieById($id) {
       // fetches record from database
       // calls getConcurrentInstance() to return an instance of MovieModel()
    }
}

您可以做的其他事情可以减少数据库的负载:

  • 每个请求只连接一次数据库。也有可能在多个请求之间共享到数据库的连接。
  • 索引数据库中经常搜索的字段。
  • 只获取你需要的记录
  • 防止两次加载相同的记录(如果它没有改变)
于 2012-10-11T06:53:00.397 回答