2010-06-21 4 views
0

나는 Zend_Cache_Backend_File과 함께 Zend_Cache_Core를 사용하여 데이터베이스에 액세스하는 모델 클래스에 대해 실행 된 쿼리 결과를 캐시합니다.PHP를 사용하여 주어진 문자열에 대한 고유 ID 생성

기본적으로 쿼리 자체는 얻은 결과를 캐시 할 ID를 형성해야하며 문제는 너무 길다. Zend_Cache_Backend_File은 예외를 throw하지 않지만 PHP는 불평하지 않지만 캐시 파일은 생성되지 않습니다.

나는과 같이 별도의 파일에 autoincrementing ID와 함께 모든 실행 쿼리를 저장, 전혀 효율적이지 해결책을 마련했습니다

0 - >> SELECT * 테이블 1 FROM >> SELECT * FROM table1, table2 2 - >> SELECT * FROM table where foo = bar

아이디어를 얻습니다. 이 방법은 모든 쿼리에 대해 고유 ID가 있습니다. 삽입, 삭제 또는 업데이트가 완료 될 때마다 캐시를 ​​정리합니다.

이제 테스트에서 캐시 2 (또는 새 ID를 추가해야하는 3 곳)에서 파일을 저장하거나 가져 오면 잠재적 인 병목 현상이 발생합니다. 파일 시스템에 대한 요청이 이루어졌습니다. 이것은 심지어 모든 것을 캐쉬 할 필요성을 무너 뜨릴 수도 있습니다. 그래서 거기에 고유 한 ID를 생성 할 수있는 방법, 즉 훨씬 짧은 표현, 파일 시스템이나 데이터베이스에 저장할 필요없이 PHP 쿼리?

답변

1

문자열은 임의 길이 때문에 분명히 이것은 불가능는 중복없이 임의의 입력 문자열을 나타낼 수있는 고정 된 크기의 ID를 만들이다. 그러나 캐싱을 위해 일반적으로 간단하고 "충분히 만족스러운"솔루션을 사용하여 충돌을 허용 가능한 수준으로 줄일 수 있습니다.

예를 들어 MD5를 사용하면 1 in 2에만 충돌이 발생합니다. 입니다. 만약 당신이 여전히 충돌에 대해 걱정하고 있다면 (아마도 안전해야만합니다) 쿼리 을 캐시의 "값"에 저장하고 실제로 값을 얻을 때를 확인할 수 있습니다 찾고 있던 쿼리.

빠른 예를 들어

(내 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]) 
+0

고맙습니다. 나는 지금 당장 그것을 시도하고있다. 두 가지 질문. 나는 해싱이 동일한 입력 문자열을 반복해서 받으면 같은 결과를 만들어야한다고 생각했다. 이게 맞지 않아? 결과 길이가 길기 때문에 쿼리 자체가 운영 체제에서 ID로 거부 된 것으로 생각하기 때문에 md5 해시의 길이는 어느 정도입니까? 고맙습니다 만, 나는 그것을 시도하고 있지만 리팩토링하는 곳이 몇 군데 있으므로 잠시 복용하고 있습니다. 결과를 따라 쿼리를 캐싱해야한다는 것을 알았습니다. – Joey

+0

이전 질문에 대한 두 가지 질문에 대한 답변을 알아 냈습니다. 답변을 게시했습니다. 하지만 난 아직도 MD5 해시와 충돌에 대해 잘 모르겠지만 누군가 제게 설명해주십시오. – Joey

+0

@Joey : 동일한 문자열을 사용하는 MD5를 사용하면 항상 동일한 출력이 생성되지만 문제는 두 개의 다른 문자열이 같은 출력을 생성 할 확률이 1 in 2^128입니다. 따라서 두 개의 서로 다른 쿼리가 동일한 MD5 키에 해시 될 수 있습니다 (가능성은 없음). 그것이 내가 거기에 여분의 수표를 추가 한 이유입니다. –

0

MD5!

Md5는 길이가 32 인 문자열을 생성합니다. 캐시 파일은 (길이가 약 47 인 파일 이름으로) 만들어 지므로 운영 체제에서 파일을 거부하지 않는 것처럼 보입니다.

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

그리고 그게 전부입니다! 그러나 충돌의 issuse가 있고 나는 테이블의 이름으로 md5 해시를 소금물에 절이는 것이 그것을 더 튼튼하게 만들어야한다고 생각합니다.

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

결과 캐싱을 구현 한 방법에 대한 전체 코드를 원할 경우 의견을 남겨 주시면 기꺼이 게시 해 드리겠습니다.