2011-02-27 2 views
0

Kohana의 ORM은 기본적으로 이미로드 된 객체를 인식 할 때 내가 원하는만큼 영리하지 않습니다.불필요한 db 히트 방지 (Kohana ORM)

$obj = $foo->bar; // hits the DB for bar 
/* ... Later ... */ 
$obj = $foo->bar; // had bar preloaded, so uses that instead 

을하지만 bar을 찾기 위해 하나 개 이상의 방법이 있다면, 그 표시되지 않습니다 그것은 예를 들어, 관계를 통해로드 된 객체들을 저장합니다. (우리가 더 많은 메타 구문 변수를 필요로)의이 foothing 모두를 가정 해 봅시다 같은 bar과의 관계가 : 나는 모델과 ID로 키가 객체의 사전로드 된 배열을함으로써이 문제를 해결하려고 시도했습니다

$obj = $foo->bar; // hits DB 

$obj = $thing->bar // hits DB again, even though it's the same object 

합니다. 그것은 작동하지만 문제는 그것이 ID를 미리 알고있는 경우에만 작동한다는 것입니다. 내 오버로드 ORM 기능은 다음과 같이 :

public function find($id = NULL) 
{ 
    $model = strtolower(get_class($this)); 

    if ($id != NULL) // notice I don't have to hit the db if it's preloaded. 
    { 
     $key = $model . '_' . $id; 
     if (array_key_exists($key, self::$preloaded)) return self::$preloaded[$key]; 
    } 

    $obj = parent::find($id); 
    $key = $model . '_' . $obj->pk(); 

    // here, I have to hit the DB even if it was preloaded, just to find the ID! 
    if (array_key_exists($key, self::$preloaded)) return self::$preloaded[$key]; 

    self::$preloaded[$key] = $obj; 
    return $obj; 
} 

이것의 목적은 그래서 두 개의 서로 다른 장소에서 같은 개체에 액세스하고, 그들이 동일한 개체이야 기회가있을 경우 잘못 반하지 않을 것이다 - 두 개의 다른 인스턴스를 업데이트하지만 사전로드 된 인스턴스 하나를 올바르게 업데이트하십시오.

위의 find 메소드는 프라이 머리 키가 아닌 다른 것으로 객체를 찾은 경우 불필요하게 DB를 찾습니다. 상상할 수있는 모든 기준에 따라 미리로드 된 객체를 키잉하지 못하게하기 위해 내가 할 수있는 일이 있습니까? 여기서 핵심적인 문제는 너무 근본적으로 보이기 때문에 원래 ORM 라이브러리의 일부가 아닌 것은 놀랍습니다. 그 이유가 있습니까, 아니면 내가 간과 한 것입니까? 이 문제를 해결하거나 해결하기 위해 대부분의 사람들은 무엇을합니까? 솔루션이 무엇이든 관계없이 Memcache를 코드에 통합 할 때이를 더 적용 할 것이므로이를 염두에 두는 것이 좋습니다.

답변

1

요청 당 DB 캐싱을 config/database.php ('캐싱'매개 변수, 기본값은 FALSE)으로 설정합니다. 이렇게하면 동일한 쿼리에 대해 캐시 된 결과를 사용할 수 있습니다.

+0

감사합니다. 아직 알지 못했습니다. 그러나 모델이 두 개의 다른 쿼리 (예 : 사용자가 서로 다른 두 가지 상황에서 다른 사용자와 상호 작용하는 경우)로 액세스하는 경우 모델은 여전히 ​​두 번로드됩니다. 그것에 대해 내가 할 수있는 일은 없습니까? – Tesserex

+1

다른 쿼리 -> 다른 모델 :) – biakaveron