[英]Generating a unique id for a given string using php
我正在使用Zend_Cache_Core和Zend_Cache_Backend_File来缓存针对访问数据库的模型类执行的查询的结果。
基本上,查询本身应该形成用于缓存获得的结果的ID,唯一的问题是它们太长了。 Zend_Cache_Backend_File不会引发异常,PHP不会抱怨,但是不会创建缓存文件。
我想出了一个效率极低的解决方案,将执行的所有查询以及自动递增的ID都存储在单独的文件中,如下所示:
0->> SELECT * FROM表1->> SELECT * FROM table1,table2 2->> SELECT * FROM表WHERE foo = bar
你明白了。 这样,我对每个查询都有唯一的ID。 每当完成插入,删除或更新时,我都会清理缓存。
现在,我确定您在这里看到了潜在的瓶颈,对于任何测试,保存或从高速缓存中获取或读取都会对文件系统发出两个(或三个,我们需要在其中添加新的ID)请求。 这甚至可以消除全部缓存的需求。 那么,有没有一种方法可以生成php中查询的唯一ID(即更短的表示形式)而不必将其存储在文件系统或数据库中?
字符串任意长,因此显然不可能创建一个固定大小的标识符来表示任意输入字符串而无需重复。 但是,出于缓存的目的,通常可以避免使用一种简单的“足够好”的解决方案,并将冲突减少到可接受的水平。
例如,您可以简单地使用MD5,它只会在2 128种情况下发生1次碰撞。 如果您仍然担心冲突(为了安全起见,您可能应该这样做),则可以将查询和结果存储在缓存的“值”中,并检查何时将值取回,它实际上是查询您正在寻找。
举个简单的例子(我的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])
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);
}
如果有人想要我实现结果缓存的完整代码,请发表评论,我很乐意将其发布。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.