2

我在 PHP 中做一个数据库类,我想在关联数组中缓存查询结果,我的想法是使用 sql 语句作为缓存数组的索引,这可能是个好主意吗?还是我应该使用 sql 中的 md5?

class DB{
const HOST = 'localhost'; //Your Database Host!
const USER = 'user'; //Your Database Username!
const PASSWORD = 'pass'; //Your Database Password!
const DATABASE = 'database'; //Your Database Name!

private static $Instance;
private static $cache = array();

private function __construct(){
    self::$Instance = mysql_connect(self::HOST, self::USER, self::PASSWORD) or die("Could not connect to database server<br/><b>Error:</b>".mysql_error());
    mysql_select_db(self::DATABASE) or die("Could not connect to database<br/><b>Error:</b>".mysql_error());
    return self::$Instance;
}

public static function DB(){
    if(!isset(self::$Instance)){
      $c = __CLASS__; 
      new $c(); 
    }
    return self::$Instance;
}

public static function QueryUnique($query){
    $query = "$query LIMIT 1";
    //$h = md5($query);
    $h = $query;
    if(isset(self::$cache[$h]))return self::$cache[$h];

    $result = mysql_query($query, self::DB());
    self::$cache[$h] = mysql_fetch_array($result);
    return self::$cache[$h];
}

}

再会

4

5 回答 5

3

在深入了解您的实现之前,您应该知道mysql 有自己的查询缓存,并且与您的实现相比,它有几个主要优势:

  • 缓存在所有PHP 请求之间共享。
  • 当表数据发生变化时,会自动清理缓存的结果。
  • 缓存被限制在一定的内存大小(很少使用的查询将被从缓存中丢弃)
于 2009-08-25T04:59:02.547 回答
1

缓存 mysql 数据可能有点冒险,它对事物做出了很多假设,但是已经说过 sql 字符串的 md5 校验和是为缓存数据生成 id 的好方法,但是您需要规范化先sql,例如:

'select 1+2'
'select 1 + 2'
' select 1 +2'

每个都会给出不同的校验和,您需要确保处理相同查询之间的任何微小差异。

于 2009-08-25T04:46:36.627 回答
1

应该不会有太大的影响,除了会额外占用一点内存,但是和查询的结果相比,我觉得不会有问题。

关联数组是有序映射,因此查找正确的索引不应该受到字符串总长度的太大影响。唯一的缺点是大多数字符串都以完全相同的文本开头。

对于您的查询,我不会依赖MD5 哈希。可能(如果不太可能)会发生哈希冲突,并且会选择完全不同的查询结果。但是,这可能是您的应用程序可接受的风险。

就个人而言,我根本不会在查询级别这样做。可缓存性通常取决于返回的数据类型。如果您在此级别缓存,您的应用程序将完全不知道它正在缓存的内容。

于 2009-08-25T04:47:24.330 回答
0

哈希 (md5, sha1) 会占用更少的内存空间。

于 2009-08-25T04:45:20.217 回答
0

如果查询很长,我会使用某种散列(如 md5):

  • 它可能会使用更少的内存(我想不是那么相关)
  • 它将允许您将其存储在其他类型的缓存中,例如文件或 APC 或 memcached 或其他任何东西,而无需更改索引。

考虑到与 md5 发生碰撞的低风险,这样做似乎并不“危险”。

我看到的唯一问题是在调试时可能会更难找到缓存数据,无论是使用var_dump调试器还是任何类型的“真实”调试器 :-(

于 2009-08-25T04:47:05.097 回答