Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何将缓存注入Zend_Db_Php_Zend Framework_Caching - Fatal编程技术网

Php 如何将缓存注入Zend_Db

Php 如何将缓存注入Zend_Db,php,zend-framework,caching,Php,Zend Framework,Caching,我正在寻找减少MySQL服务器上执行的查询数量的方法 应用程序服务器和数据库服务器位于不同的计算机上,因此在应用程序服务器上缓存以前的查询结果似乎不是一个好的选择。显然还有其他一些策略,比如减少查询数量和优化查询语句,但是我认为我不应该将查询缓存作为一种选择 我最初认为我可以轻松地在Zend_Db对象中打开某种形式的查询缓存,但是我最近看到的横切是Zend_Db_分析器 我考虑的一种方法是为我的Zend\u Db\u适配器对象创建一个代理。大意是: /** * Initialize the d

我正在寻找减少MySQL服务器上执行的查询数量的方法

应用程序服务器和数据库服务器位于不同的计算机上,因此在应用程序服务器上缓存以前的查询结果似乎不是一个好的选择。显然还有其他一些策略,比如减少查询数量和优化查询语句,但是我认为我不应该将查询缓存作为一种选择

我最初认为我可以轻松地在
Zend_Db
对象中打开某种形式的查询缓存,但是我最近看到的横切是
Zend_Db_分析器

我考虑的一种方法是为我的
Zend\u Db\u适配器
对象创建一个代理。大意是:

/**
 * Initialize the database.
 *
 * @return void
 */
protected function _initDb() {
    // Instantiate a connection to the database
    $config = Zend_Registry::get('config');
    $db = new MyProject_Db_Proxy (
                Zend_Db::factory($config->resources->db->adapter, 
                                 $config->resources->db->params)
              );

    // Store the database object in the registry
    Zend_Registry::set('db', $db);

    Zend_Db_Table::setDefaultAdapter('db');
}
public MyProject_Db_Proxy() {

  private $_adapter = null;
  ...
  public function query($sql, $bind = array()) {
    // Generate the cache key by joining and hashing $sql and $bind
    // Check to see if key is in cache, return if found
    // Execute query
    $stmt = this->_adapter->query($sql, $bind);
    // Cache result
  }
  ...
}
我已经浏览了各种
Zend\u Db
接口和类,似乎可以通过代理将缓存注入
Zend\u Db\u适配器\u Abstract::query()
方法。大意是:

/**
 * Initialize the database.
 *
 * @return void
 */
protected function _initDb() {
    // Instantiate a connection to the database
    $config = Zend_Registry::get('config');
    $db = new MyProject_Db_Proxy (
                Zend_Db::factory($config->resources->db->adapter, 
                                 $config->resources->db->params)
              );

    // Store the database object in the registry
    Zend_Registry::set('db', $db);

    Zend_Db_Table::setDefaultAdapter('db');
}
public MyProject_Db_Proxy() {

  private $_adapter = null;
  ...
  public function query($sql, $bind = array()) {
    // Generate the cache key by joining and hashing $sql and $bind
    // Check to see if key is in cache, return if found
    // Execute query
    $stmt = this->_adapter->query($sql, $bind);
    // Cache result
  }
  ...
}

我的问题是:有没有更好/更简单的方法将缓存注入Zend_Db?

我会避免直接将缓存注入Zend_Db

如果有一个查询需要缓存24小时,而另一个查询只需要缓存60秒,该怎么办?你如何/在哪里控制?此外,还需要逻辑来确保它只缓存SELECT查询,否则会浪费缓存空间

我只需要使用您选择的适配器(libmemcached/apc/xcache以获得最佳性能)使用Zend_缓存,并在应用程序或数据访问类中处理缓存

您可以使用查询本身的哈希作为缓存键,或者根据查询数据,为更容易识别的特定查询创建哈希函数。例如,如果有一个查询刚刚从数据库中提取了用户帐户详细信息,那么缓存键可能类似于
userInfoQuery:1234
,其中1234是用户id

查询缓存不返回过时数据。修改表时,将刷新查询缓存中的所有相关条目。

因此,如果表因insert/update/delete而更改,则查询缓存将被清除。如果表经常更改,那么查询缓存就没有多大帮助,因为它是短期的


在Zend_Db的生产中,您应该做的另一件常见的事情是缓存表元数据。您可能已经注意到,Zend问题描述了insert()、find()或info()查询之前的查询。使用表元缓存可以消除这些查询。请参阅以了解如何执行此操作的说明。

启用数据库查询缓存。请注意,我正在使用Zend Framework 1.11.11和PDO MySQL适配器。@hakre您是否建议数据库查询缓存将消除网络往返?你能给我指一下这方面的资源吗?不,这不适用于网络往返。如果要防止网络往返,需要客户端查询缓存,请参阅@hakre,我会记住该插件。它是相当新的,可能需要数据库升级,但它可能是一个选项。我的方法基本上是相同的,只是我将其全部下推到一个存储库/服务类中,该类由一个正确配置的(生命周期等)Zend_缓存
实例提供。repo/服务中的所有这些数据访问方法都在执行昂贵的db操作之前执行缓存检查。另外,不要忘记,正如Drew所指出的,当您更新数据库中会影响select查询结果的任何数据时,您可能希望清除所有受影响的缓存项。谢谢您的回答@drew010。元数据缓存似乎是一个很容易立即实现的选项。我非常喜欢DRY,所以我希望如果键入缓存返回值,或者执行查询、缓存结果和返回逻辑,将数量降至最低。也许在我的映射器中进行一些重构,这可能会成为一个更好的选择。