Nasıl Hazırlanan Tablolar ile memcached kullanabilirim?

1 Cevap php

Normal SQL sorguları önbelleğe yeterince basittir.

public function query($sql) {

    if( $result = cache::get(sha1($sql)) ) {
    	return $result;
    }

    $result = $this->connection->query($sql);
    cache::set(sha1($sql), $result);
    return $result;
}

Ama sorgu deyimi sonrasına kadar ne olacağını bilmiyorum çünkü sen hazırlanıp sorgular nasıl önbelleğe yok zaten hazırlanır ve daha sonra veri bağlı?

$sth = $dbh->prepare('SELECT * FROM table WHERE id = ?');

...later...

$sth->bindParam(1, $id);
$sth->execute();

İlk olarak, ifadeleri veritabanı kaynak kimlikleri uzun ömürlü ve olamaz çünkü '(bu-> ifadeler [] $ bir dizi gibi) sayfa başına önbelleğe alınır: Ben bu iki parçalı bir cevap olduğunu duygu olsun t dosyaları veya bir şey saklanır.

Ifadeleri idam edilmeden önce ikinci, () biz (PDOStatement::queryString ile kolay) artı params sağlamalarının verilen deyimi oluşturmak için kullanılan sql karma tarafından sonuçlar için memcached / filecache bakın. Sorun deyimi nesne params bulgudur.

Tabii ki, bu sadece bir fikir olduğunu ve muhtemelen daha iyi çözümler vardır.

1 Cevap

Peki, sizin önbellek anahtarının için params her değer katmak gerekir. Böyle bir şey:

public function stmt($sql, $params) {

    $cache_key = sha1($sql . serialize($params));

    if( $result = cache::get($cache_key) ) {
        return $result;
    }

    $sth = $this->connection->prepare($sql);

    $i = 0;
    foreach ($params as &$param)
    {
        $sth->bindParam(++$i, $param);
        $sth->execute();
    }
    unset($param)

    // fetch all the rows into $result

    cache::set($cache_key, $result);
    return $result;
}

$obj->stmt('SELECT * FROM table WHERE id = ?', array(&$id));

Ben, sizin ihtiyaçlarınıza uyarlamak için size bırakacağım. Sen satırlarını ve onları bir diziye saklamak gerekir.


Burada kullanmak zorunda sargının tür:

class stmt
{
    protected $sth, $sql, $cache, $params = array();

    public function __construct($dbh, $sql)
    {
        $this->sth = $dbh->prepare($sql);
        $this->sql = $sql;
    }

    public function bindParam($param, &$var)
    {
        $this->params[$param] =& $var;
        return $this->sth->bindParam($param, $var);

        // or, if you want to support all the args
        $args = func_get_args();
        $args[1] =& $var;

        return call_user_func_array(array($this->sth, 'bindParam'), $args);
    }

    public function execute(array $params = null)
    {
        $str = serialize(isset($params) ? $params : $this->params);
        $cache_key = sha1($this->sql . $str);

        // insert cache logic here...

        if (isset($params))
        {
            $this->stmt->execute($params);
        }
        else
        {
            $this->stmt->execute();
        }

        $this->cache = $this->stmt->fetchAll();

        // save cache here
    }

    public function fetch()
    {
        return array_shift($this->cache);
    }
}

Eğer kullanmayı planladığınız her PDOStatement yöntemi maç olurdu. PDO :: FETCH_INTO de, uygulamak için bir tür acı olacaktır. Benim tavsiyem: Kendi kullanım odaklanmak. Belki de kapalılıklarda düzeyde bir önbellek uygulamak zorunda değilsiniz ve bunun yerine onu sayar, sadece önbellek yetenekleri ekleyebilirsiniz.

Her neyse, yazmak daha kod, daha kod korumak ve daha büyük olasılıkla sizin uygulamada hatalar tanıtacak olan gerekecek unutmayın. Yani kendi iyiliği için çok akıllı olmaya çalışacaktı bir önbelleğe alma tabakasının maliyet / fayda analizi ile dikkatli olun :)