使用php为给定字符串生成唯一ID

时间:2010-06-21 01:17:12

标签: php unique zend-cache

我正在使用Zend_Cache_Core和Zend_Cache_Backend_File来缓存为访问数据库的模型类执行的查询结果。

基本上查询本身应该形成用于缓存获得结果的id,唯一的问题是,它们太长。 Zend_Cache_Backend_File不会抛出异常,PHP不会抱怨但是没有创建缓存文件。

我提出了一个根本没有效率的解决方案,将任何已执行的查询与自动增量ID存储在一个单独的文件中,如下所示:

0->> SELECT * FROM table 1->> SELECT * FROM table1,table2 2->> SELECT * FROM表WHERE foo = bar

你明白了;这样我每个查询都有一个唯一的id。每当完成插入,删除或更新时,我都会清理缓存。

现在我确定你看到了潜在的瓶颈,对于任何测试,保存或从缓存中获取两个(或三个,我们需要添加一个新的id)请求是对文件系统的。这甚至可能无法完全缓存。那么我有没有办法在php中生成一个唯一的id,即一个更短的表示,而不必将它们存储在文件系统或数据库中?

2 个答案:

答案 0 :(得分:1)

字符串是任意长的,所以显然不可能创建一个固定大小的标识符,可以表示任意输入字符串而不重复。但是,出于缓存的目的,您通常可以使用简单“足够好”的解决方案,并将冲突降低到可接受的水平。

例如,您可以简单地使用MD5,它只会在1个2 sup <128> 的情况下产生碰撞。如果您仍然担心冲突(并且您可能应该这样做,只是为了安全起见),您可以将查询存储在缓存的“值”中,并检查何时获得值回来它实际上是你正在寻找的查询。

作为一个简单的例子(我的PHP有点生疏,但希望你明白了):

$query = "SELECT * FROM ...";

$key = "hash-" + hash("md5", $query);
$result = $cache->load($key);
if ($result == null || $result[0] != $query) {
    // object wasn't in cache, do the real fetch and store it
    $result = $db->execute($query); // etc

    $result = array($query, $result);
    $cache->save($result, $key);
}

// the result is now in $result[1] (the original query is in $result[0])

答案 1 :(得分:0)

MD5 !!

Md5生成一个长度为32的字符串,似乎工作正常,创建了缓存文件(文件名大小约为47),所以好像操作系统不会拒绝它们。

//returns id for a given query
function getCacheId($query) {
    return md5($query);
}

就是这样!但是有一些冲突的发生,我认为腌制md5哈希(可能是表的名称)应该会使它更加健壮。

//returns id for a given query
function getCacheId($query, $table) {
    return md5($table . $query);
}

如果有人想要我已经实现结果缓存的完整代码,请发表评论,我会很乐意发布。