2

私はこのような機能を持っています:

function query($query)
{
    /* If query result is in cache already, pull it */
    if $cache->has(md5($query))
       return $cache->get(md5($query));

    /* Do the actual query here. mysqli_query() etc, whatever u imagine. */

    /* Set the cache with 10 minute expiration */
    $cache->set(md5($query), $queryOutput, array(10)); 
}

基本的に、クエリを実行するSELECT * FROM USERSと、自動的に 10 分間キャッシュされます。

md5 が信頼できるかどうかはわかりません。1 回で 32 文字の文字列が作成されますが、これは少し過剰に聞こえます。第二に、md5 は、特定の入力の出力と同じ文字列を与えることが知られています。一意のキャッシュ キーを識別するための md5 の代替手段はありますか? 2 つの完全に異なる SQL クエリが同じ md5 出力を取得し、Web サイトの一部のページが破損する可能性はほとんどありませんが、今すぐ予測してそれに応じてコーディングする必要がある可能性はまだあります。

もう1つ、このような関数の使用は悪い習慣と見なされているように感じます。USERS tableキャッシュの後に新しいユーザーが挿入される可能性がありますがSELECT * FROM USERS、それでも同じ md5 出力が得られるため、新しく挿入されたユーザーを無視します。10 分間に数回、同じニックネームで登録する場合があります。

機密性の高いクエリに 2 番目のパラメーターを渡す必要がありますquery($query, 'IGNORECACHE')か? 私には論理的に聞こえません。心に留めておくべきことが多すぎるでしょう。皆さんは、このような問題をどのように処理していますか?

この場合の md5 の代替案に関する最初の質問に回答していただければ幸いです。また、2 番目の質問で SQL キャッシュの適切な使用法について簡単に説明していただければ幸いです。

ありがとうございました。

4

2 に答える 2

4

ハッシュの衝突(つまり、同じmd5を持つ2つのクエリ)が発生することが心配な場合は、クエリ自体をキーとして使用してください。

if $cache->has($query)
    return $cache->get($query);
$cache->set($query, $queryOutput, array(10)); 

または、 sha1を使用することもできます。より長い文字列を返すため、衝突の可能性は低くなります。

32バイトまたは40バイトをキャッシュキーとして保存することについて心配する必要はありません。これは、Webアプリケーションのパフォーマンスに大きな影響を与えることはありません。

MySQLには独自のクエリキャッシュもあります。同じクエリを再度実行すると、MySQLはそのクエリをキャッシュから取得します。ユーザーをusersテーブルに挿入すると、MySQLはキャッシュを使用できなくなったことを認識しますが、これはキャッシュクラスには当てはまりません。

于 2013-03-12T14:26:28.317 に答える
2

衝突の可能性が非常に低いため、md5をある程度安全に使用できます。ニーズに合う可能性のある別のソリューションは、クエリタイプによってキャッシュキーに名前を付け、適切なセパレータを使用してパラメータを追加することです。

$result = $cache->get('userdata_'.$userId);

不注意に使用すると、データベース内のデータが変更されても古いデータがキャッシュに残っている場合に、キャッシュによって予期しない問題が発生する可能性があります。データを追加/変更/削除するときに、キャッシュを無効にする方法があり、関連するすべてのキャッシュに対して無効にする方法があることを確認してください。

于 2013-03-12T14:27:40.643 に答える