資料快取

資料快取即儲存一些 PHP 變數到快取中,以後再從快取中取出來。出於此目的,快取元件的基礎類別 CCache 提供了兩個最常用的方法: set()get()

要在快取中儲存一個變數 $value ,我們選擇一個唯一 ID 並調用 set() 儲存它:



快取的資料將一直留在快取中,除非它由於某些快取策略(例如快取空間已滿,舊的資料被刪除)而被清除。 要改變這種行為,我們可以在調用 set() 的同時提供一個過期參數,這樣在設定的時間段之後,快取資料將被清除:



稍後當我們需要存取此變數時(在同一個或不同的 Web 請求中),就可以通過 ID 調用 get() 從快取中將其取回。 如果返回的是 false,表示此值在快取中不可用,我們應該重新產生它。



為要存入快取的變數選擇 ID 時,要確保此 ID 對應用程式中所有其他存入快取的變數是唯一的。 而在不同的應用程式之間,這個 ID 不需要是唯一的。快取元件具有足夠的智慧區分不同應用程式中的 ID。

一些快取儲存裝置,例如 MemCache, APC, 支援以批次模式取得多個快取值。這可以減少取得快取資料時帶來的開銷。Yii 提供了一個名為 mget() 的方法來完成此功能。如果底層快取儲存裝置不支援此功能,mget() 依然可以模擬實現它。

要從快取中清除一個快取值,調用 delete(); 要清除快取中的所有資料,調用 flush()。 當調用 flush() 時一定要小心,因為它會同時清除其他應用程式中的快取。

提示: 由於 CCache 實現了 ArrayAccess,快取元件也可以像一個陣列一樣使用。下面是幾個例子:


快取相依性

除了過期設置,快取資料也可能會因為相依性條件發生變化而失效。例如,如果我們快取了某些文件的內容,而這些文件發生了改變,我們就應該讓快取的資料失效, 並從文件中讀取最新內容而不是從快取中讀取。

我們將一個相依性關係顯示為一個 CCacheDependency 或其子類別的實體。 當調用 set() 時,我們連同要快取的資料將其一同傳入。



現在如果我們通過調用 get() 從快取中取得 $value ,相依性關係將被檢查,如果發生改變,我們將會得到一個 false 值,表示資料需要被重新產生。

下面是可用的快取相依性的簡要說明:

查詢快取

從版本 1.1.7,Yii 開始支援查詢快取。建立在資料快取上,查詢快取儲存資料庫查詢的結果在快取中,藉此省下未來同樣的資料庫查詢要求的時間,直接由快取提供。

提示: 某些資料庫(例如:MySQL)也支援查詢快取的功能。跟 MySQL 相比,Yii 提供更有彈性且更有效率的查詢快取。

啟用查詢快取

要啟用查詢快取,確認 CDbConnection::queryCacheID 指定到一個有效的快取應用程式元件(預設是 cache)。

一起使用資料存取物件和查詢快取

要使用查詢快取,呼叫 CDbConnection::cache() 方法當我們進行資料庫查詢。如下所示:



當執行上述述句,Yii 會先檢查快取是否包含有正要執行的 SQL 述句有效的快取結果。藉由下述三個條件驗證:

如果上述條件都符合,快取結果會被直接從快取中回傳。否則,SQL 述句會被送到資料庫執行,執行結果會被儲存在快取中再回傳。

一起使用 ActiveRecord 和查詢快取

查詢快取可以跟 Active Record 一起使用。為此,我們呼叫一個相似的 CActiveRecord::cache() 方法如下:



這裡的 cache() 其實就是 CDbConnection::cache()。從內部觀察,當執行 AR 產生的 SQL 述句,Yii 會嘗試使用我們上述的查詢快取。

快取多個查詢

預設,每次我們呼叫 cache() 方法(不論 CDbConnectionCActiveRecord),他會把下個要執行的 SQL 查詢標記快取。其他的 SQL 查詢就不會被快取,除非我們再次呼叫 cache()。例如,



藉由提供額外的 $queryCount 參數給 cache() 方法,我們可以強迫多個查詢使用查詢快取。下面的例子,當我們呼叫 cache(),我們指定下兩個查詢也要被快取:



如你所知,當進行關聯式 AR 查詢,多個 SQL 查詢是有可能被執行的(藉由檢查 log messages)。例如,如果 PostComment 的關係是 HAS_MANY,那麼下列的程式碼會實際上執行了兩個查詢:



如果我們使用查詢快取如下,那只有第一個查詢會被快取:



為了快取這兩個查詢,我們需要提供額外的參數,說明有多少個資料庫查詢要快取:



限制

快取查詢沒辦法運作在包含有資源句柄的結果。例如,當使用 BLOB 欄位類型,某些資料庫會回傳包含有資源句柄的欄位資料。

某些快取裝置有大小限制。例如,memcache 限制每個項目最大的容量為 1MB。因此,如果查詢結果的大小超出這個限制,快取會失敗。

$Id$