PHPコード
SQLクエリキャッシュ
読者に最適です
このチュートリアルは、SQL クエリをキャッシュしてデータベース接続と実行の負荷を軽減し、スクリプトのパフォーマンスを向上させることに関心がある PHP プログラマーに適しています。
概要
多くのサイトは、サイト データ ストレージのコンテナとしてデータベースを使用します。データベースには製品情報、ディレクトリ構造、記事、ゲストブックが含まれており、一部のデータは完全に静的である可能性があり、これらはキャッシュ システムの恩恵を大きく受けます。
このようなシステムは、SQL クエリの結果をシステム上のファイルにキャッシュすることで、データベースの接続、クエリの構築、返された結果の取得を防止することで応答時間を改善します。
一部のシステム データベースは WEB サーバー上に配置されていないため、リモート接続 (TCP など) が必要になるか、データベースから大量のデータを取得する必要があるため、システムの応答時間に応じてさらに時間がかかります。そしてリソースの使用。
前提条件
このチュートリアルでは、データベースとして MySQL を使用します。 MySQL をインストールし (www.mysql.com ダウンロードが可能です)、PHP MYSQL 拡張機能をアクティブ化する必要があります (デフォルトでアクティブ化されています)。
データベースにクエリを実行する必要があるため、SQL (構造化クエリ言語) の基本的な知識を知っている必要があります。
SQL クエリ結果のキャッシュ
クエリ結果をキャッシュする理由
クエリ結果をキャッシュすると、スクリプトの実行時間とリソース要件が大幅に改善されます。
SQL クエリ結果をキャッシュすると、データを後処理することもできます。ファイル キャッシュを使用してスクリプトの出力全体 (HTML 出力) を保存する場合、これは機能しない可能性があります。
SQL クエリを実行すると、Diandian の処理プロセスは次のようになります:
l データベースに接続します
l SQLクエリを準備します
l クエリをデータベースに送信します
l 戻り結果を取得します
l データベース接続を閉じます
上記の方法はリソースを非常に大量に消費するため、スクリプトのパフォーマンスに悪影響を及ぼします。これは、返される大量のデータの取得とデータベース サーバーの場所の 2 つの要素によってのみ調整できます。継続的に接続すると、データベースに接続する際の負荷が軽減されますが、大量のデータを取得すると、メモリ リソースが非常に消費され、全体の保存時間が非常に短くなります。
SQL クエリを作成します:
SQL (Structured Query Language) クエリは、データベースとその内容を操作するためのインターフェイスとして使用されます。 SQL を使用すると、テーブルの構造の定義と編集、テーブルへのデータの挿入、テーブル内の情報の更新または削除ができます。
SQL は、データと通信するために使用される言語です。ほとんどの PHP データベース拡張機能 (MySQL、ODBC、Oracle など) では、SQL クエリをデータベースに渡すことによってプロセス全体が管理されます。
このチュートリアルでは、データベース内のデータを取得するために選択言語のみが使用されます。このデータはキャッシュされ、後でデータ ソースとして使用されます。
キャッシュをいつ更新するかを決定します:
キャッシュには、プログラムのニーズに応じてさまざまな形式があります。最も一般的な 3 つの方法は次のとおりです:
l 時間トリガーキャッシュ (期限切れのタイムスタンプ)
l コンテンツの変更によりキャッシュがトリガーされます (データの変更が検出されると、それに応じてキャッシュが更新されます)
l キャッシュを手動でトリガーします (情報の有効期限が切れたことをシステムに手動で通知し、新しいキャッシュを強制します)
キャッシュのニーズは、上記の原則の 1 つまたは複数の組み合わせである可能性があります。このチュートリアルでは、時間トリガーの方法について説明します。ただし、包括的なキャッシュ メカニズムでは、3 つの方法を組み合わせて使用します。
キャッシュされた結果:
基本的なキャッシュは、PHP の 2 つの関数 Serialize() と unserialize() を使用します (注釈: これら 2 つの関数はそれぞれシリアル化と逆シリアル化を表します)。
Serialize() 関数は PHP 値を保存するために使用され、これらの値の型と構造が失われないようにします。
実際、PHP のセッション拡張機能はシリアル化された変数を使用し、セッション変数 ($_SESSION) をシステム上のファイルに保存します。
関数 unserialize() は上記の操作の逆を行い、シリアル化された文字列を元の構造とデータ内容に戻します。
この場合、電子商取引ストアを考えてみましょう。ストアには、カテゴリと製品という 2 つの基本テーブルがあります (ここでは、元のデータベース テーブル名を示します)。製品テーブルは毎日変更される可能性がありますが、カテゴリは静的なままです。
製品を表示するには、出力キャッシュ スクリプトを使用して、出力 HTML 結果をファイルに保存します。ただし、カテゴリ テーブルには後処理が必要な場合があります。たとえば、変数 category_id ($_REQUEST['category_id'] で取得) を介してすべてのカテゴリが表示されている場合、現在選択されているカテゴリを強調表示することができます。
テーブルのカテゴリ構造
フィールド
を入力してください
鍵
追加
カテゴリID
カテゴリ名
カテゴリ説明
int(10) 符号なし
varchar(255)
テキスト
プリ
auto_incremen
この例では、時間トリガー キャッシュ テクノロジを使用して、キャッシュされた SQL 出力が一定期間後に期限切れになるように設定しています。この特定の例では、期間は 24 時間です。
シリアル化の例:
l データベースに接続します
l クエリを実行します
l すべての結果を取得して配列を形成し、後でアクセスできるようにします
l シリアル化された配列
l シリアル化された配列をファイルに保存します
$file = 'sql_cache.txt';
$link = mysql_connect('localhost','ユーザー名','パスワード')
あるいは死ぬ (mysql_error());
mysql_select_db('ショップ')
あるいは死ぬ (mysql_error());
/* SQL クエリを構築します */
$query = "カテゴリから * 選択";
$result = mysql_query($query)
あるいは死ぬ (mysql_error());
while ($record = mysql_fetch_array($result) )
{
$レコード[] = $レコード
}
$OUTPUT = シリアル化($レコード);
$fp = fopen($file,"w") // 書き込み権限でファイルを開きます
;
fputs($fp, $OUTPUT);
fclose($fp);
sql_cache.txt ファイルを確認してください。内容は次のようになります:
a:1:{i:0;a:6:{i:0;s:1:"1";s:11:"category_id";s:1:"1";i:1;s:9: "コンピューター";s:13:"カテゴリ名";s:9:
"コンピューター" ;i:2;s:25:"コンピューターの説明";s:20:"category_description"
;s:25:"コンピュータの説明";}}
この出力は、その変数と型の内部表現です。 mysql_fetch_array() 関数を使用して、数値インデックス付き配列と連想配列 (データが 2 回発生しているように見えるのはこのためです) を返し、一方は数値インデックスを持ち、もう一方は文字列インデックスを持っているとします。
キャッシュを使用する:
キャッシュを使用するには、関数 unserialize() を使用してデータを元の形式と型に復元する必要があります。
file_get_contents() 関数を使用すると、sql_cache.txt ファイルの内容を読み取り、それを変数に割り当てることができます。
注意: この関数は PHP4.3.0 以降で有効です。古いバージョンの PHP を使用している場合、簡単な方法は、file() 関数を使用することです (ファイル全体を配列に読み取り、各行が配列になります)。 implode() 関数は、配列の要素を文字列に連結するために使用され、次に unserialize() を使用してそれを逆シリアル化します。
// file_get_contents() は PHP 4.3.0 未満に適しています
$file = 'sql_cache.txt';
$records = unserialize(implode('',file($file)));
これで、 $records 配列を渡して元のクエリ データを取得できるようになります:
foreach ($records as $id=>$row) {
$row['category_name']."
" を印刷します。
}
$records は配列内の行であることに注意してください (クエリ結果を含む数値インデックス付きの列 - 各行は数値と文字列です...なんて面倒なことでしょう)。
それらをまとめてください:
この例では、時間に基づいてキャッシュするかどうかを決定します。ファイル変更タイムスタンプが現在のタイムスタンプから有効期限タイムスタンプを引いたものより大きい場合はキャッシュが使用され、それ以外の場合はキャッシュが更新されます。
l ファイルが存在し、タイムスタンプが設定された有効期限よりも小さいかどうかを確認します
l キャッシュ ファイルに保存されているレコードを取得するか、キャッシュ ファイルを更新します
$file = 'sql_cache.txt';
$expire = 86400 // 24 時間 (単位: 秒)
if (file_exists($file) &&
filemtime($file) > (time() - $expire))
{
// キャッシュ内のレコードを取得します
$records = unserialize(file_get_contents($file));
} その他 {
//serialize() 関数を通じてキャッシュを作成します
}
追加の可能性:
l キャッシュされた結果を共有メモリに保存して高速化します
l -- - – ランダムに機能を追加しましたSQL クエリを実行し、出力がキャッシュされた出力と一致しているかどうかを確認します。矛盾している場合は、キャッシュを更新します (この機能が実行される確率は 1/100 に設定できます)。ハッシュ アルゴリズム (MD5() など) は、文字列またはファイルが変更されたかどうかを判断するのに役立ちます。
l このキャッシュ ファイルを手動で削除してキャッシュを強制的に更新する管理者関数を追加します (file_exists() 関数が false を返した場合など)。 unlink() 関数を使用してファイルを削除できます。
脚本:
$file = 'sql_cache.txt';
$expire = 86400 // 24 時間
;
if (file_exists($file) &&
filemtime($file) > (time() - $expire)) {
$records = unserialize(file_get_contents($file));
} その他 {
$link = mysql_connect('localhost','ユーザー名','パスワード')
死ぬか (mysql_error());
Mysql_select_db('ショップ')
死ぬか (mysql_error());
/* SQL クエリを構築します */
$query = "カテゴリから * 選択";
$result = mysql_query($query)
死ぬか (mysql_error());
While ($record = mysql_fetch_array($result) ) {
$records[] = $record;
}
$OUTPUT = シリアル化($レコード);
$fp = fopen($file,"w");
fputs($fp, $OUTPUT);
fclose($fp);
} // 終了 else
//クエリ結果は配列 $records にあります
foreach ($records as $id=>$row) {
If ($row['category_id'] == $_REQUEST['category_id']) {
// 選択したディレクトリは太字で表示されます
print ''.$row['category_name'].'
';
} その他 {
// 他のディレクトリは通常のフォントで表示されます
print $row['category_name'].'
';
}
} // foreach の終了
著者「tw5566」