データキャッシュ

データキャッシュは、PHP 変数をキャッシュし、後でそのキャッシュから読み込めるようにします。 この目的のために、キャッシュコンポーネントのベースクラス CCache は、多くの場合に利用される set()get() の二つのメソッドを提供します。

キャッシュに変数 $value を保存するには、ユニークな ID を選んで set() を呼びます:



キャッシュされたデータは、キャッシングポリシー (たとえば、キャッシュ容量がいっぱいになれば、一番古いデータが削除されます) のために、キャッシュが消されない限りずっと残ります。 この挙動を変えるために、set() を呼ぶときに、有効期限パラメータを指定し、一定の期間の後、キャッシュが削除されるようにする事もできます。



後で (同じウェブリクエスト、あるいは、別のウェブリクエストの中で) この変数にアクセスする必要が生じときに、その ID を指定して get() を呼ぶと、キャッシュから変数を読み込むことが出来ます。 返り値が false である場合は、変数の値がキャッシュの中に無いことを意味しますので、値を再生成する必要があります。



キャッシュされる変数のために ID を選ぶときは、アプリケーション中でキャッシュされる可能性のある他の全ての変数の中で、ユニークな ID が割り当てられるように保証してください。 ID は、アプリケーションをまたいでユニークになるように指定する必要はありません。 キャッシュコンポーネントは、異なるアプリケーションに対しては、自動的に異なる ID を割り当てます。

MemCache や APC のようなある種のキャッシュストレージにおいては、バッチモードにより複数のキャッシュデータを獲得する手段がサポートされており、これを利用すると、キャッシュ獲得のオーバヘッドを低減することが出来ます。 この機能を利用するために mget() という名のメソッドが提供されています。 裏打ちするキャッシュストレージがサポートしていない場合でも、mget() はこの機能をシミュレートして動作します。

キャッシュから、キャッシュされた値を削除するには、delete() を呼びます。 また、全てのキャッシュを削除するには、flush() を呼びます。 flush() は、他のアプリケーションのデータも含めて、全てのキャッシュデータを削除しますので、このメソッドを呼ぶ際は、細心の注意を払ってください。

ヒント: CCacheArrayAccess により実装されているため、 キャッシュコンポーネントは配列のように扱えます。下記に例を示します:


キャッシュ依存関係

キャッシュデータは、有効期限の設定に加えて、依存関係のあるデータの変更によって無効になる可能性があります。 たとえば、あるファイルの内容をキャッシュに保存している場合、ファイルが変更されたときには、キャッシュされたコピーを無効にし、キャッシュではなくファイルから最新のデータを読み込む必要があります。

この依存関係は CCacheDependency またはその子クラスのインスタンスとして表わされます。 set() を呼ぶ際に、キャッシュされるデータと共に、依存関係のインスタンスを指定します。



今、get() を呼び出してキャッシュから $value を取り出そうとすると、依存関係が調査されます。 そして、依存関係が変更されていれば、データを再生成する必要があることを知らせるために、get() は false の値を返します。

以下は、利用可能なキャッシュ依存関係の概要です:

クエリキャッシング

バージョン 1.1.7 以降、Yii はクエリキャッシングのサポートを追加しました。 クエリキャッシングは、データキャッシュの上に構築されており、DB クエリの結果をキャッシュに格納します。 そのため、将来同じクエリが要求された場合に、結果を直接キャッシュから得られるため、DB クエリの実行時間を短縮することが出来ます。

情報: ある種の DBMS (例えば MySQL) は、DB サーバサイドでのクエリキャッシュもサポートしています。 このサーバサイドでのクエリキャッシングと比較すると、Yii がここでサポートする同じ機能は、 より一層柔軟であり、潜在的にはより一層効率的でしょう。

クエリキャッシングを有効にする

クエリキャッシングを有効にするには CDbConnection::queryCacheID が正当なキャッシュアプリケーションコンポーネント (デフォルトではcache) を参照するようにしてください。

DAO と共にクエリキャッシングを使用する

クエリキャッシングを使うには、DB クエリを行う際に CDbConnection::cache() メソッドをコールします。 例を示します。



上記の文を実行する際に、Yii は、実行される SQL 文の正当な結果がキャッシュの中に有るかどうかを最初にチェックします。 このチェックは、以下の3つの条件をチェックすることによって行なわれます。

もし上記すべての条件が満たされていれば、キャッシュされた結果が直接キャッシュから返されます。 そうでなければ、SQL 文が DB サーバへ送信されて実行され、対応する結果がキャッシュに格納されて返されます。

アクティブレコードと共にクエリキャッシングを使う

クエリキャッシングは アクティブレコード と共に使用することも可能です。 そうするには、同様の CActiveRecord::cache() メソッドを以下のように呼び出します。



ここでの cache() メソッドは本質的には CDbConnection::cache() へのショートカットです。 内部的にはアクティブレコードによって生成された SQL 文を実行する際に、Yii が前節で示したようなクエリキャッシングを行います。

複数クエリのキャッシング

デフォルトでは、CDbConnection または CActiveRecord のどちらであっても、cache() メソッドを呼び出すたびに、次に実行する SQL クエリがキャッシュされる対象としてマークされます。 その他の SQL クエリは、cache() を再び呼ばない限り、キャッシュされません。 例えば、



cache() メソッドに追加の $queryCount パラメータを供給することにより、複数のクエリに対してクエリキャッシングを行わせることが可能です。 次の例では、cache() をコールするときに、次の二つのクエリについて、クエリキャッシングを実行すべきことを指定しています。



周知のとおり、リレーショナルアクティブレコードのクエリを実行するときは、複数の SQL クエリが実行されます (ロギングで確認できます)。 例えば、PostComment の関係が HAS_MANY である場合、以下のコードは、実際には、二つの DB クエリを実行します。



以下のようにクエリキャッシングを行うと、最初の DB クエリだけがキャッシュされます。



両方の DB クエリをキャッシュするためには、追加のパラメータを与えて、次に何個の DB クエリをキャッシュしたいかを示さなければなりません。



制約

リソースハンドルを返すようなクエリにはクエリキャッシュは働きません。 例えばある種の DBMS において BLOB カラムタイプを用いる場合、クエリの結果はカラムデータについてリソースハンドルを返します。

ある種のキャッシュストレージはサイズに制約があります。 例えば、memcache では、各エントリのサイズは 1MB が上限値です。 そのため、クエリの結果のサイズがこの制約を越える場合、キャッシュは失敗します。

$Id$