ETag自体に入るアイテムを利用できるようにするためのコストに依存すると思います.
つまり、ユーザーは特定のリソースに対する要求を送信します。これにより、データベースでの取得操作 (またはその他の操作) がトリガーされます。
取得がファイルのフェッチなどの単純なものである場合、ファイルの統計情報の照会は高速であり、どこにも何も保存する必要はありません。ファイル パスの MD5 とその更新時間で十分です。
検索がデータベースへのクエリを意味する場合は、パフォーマンスを損なうことなくクエリを分解できるかどうかに依存します (たとえば、ユーザーが ID で記事を要求します。記事テーブルからのみ関連データを取得する場合があります。したがって、キャッシュの「ヒット」は主キーに対する単一の SELECT を必要としますが、キャッシュの「ミス」は、データベースに対して再度クエリを実行する必要があることを意味し、最初のクエリを無駄にするかどうかはモデルによって異なります)。
クエリ (または一連のクエリ) が十分に分解可能 (および結果のコードが保守可能) である場合は、動的 ETag を再度使用します。
そうでない場合、ほとんどは、クエリのコストと、保存された ETag ソリューションの全体的なメンテナンス コストに依存します。クエリのコストが高く (または出力がかさばり)、INSERT/UPDATE が少ない場合 (その場合のみ)、ETag を使用してセカンダリ列 (またはテーブル) を格納すると有利です。
キャッシングミドルウェアについては、わかりません。すべてを追跡するフレームワークがあれば、「がんばれ」と言うかもしれません。ミドルウェアは、上記の点を考慮して実装する必要があります。ミドルウェアが実装にとらわれない場合 (前代未聞ではないカット アンド ペーストの平手打ちでない限り、可能性は低い)、リソースへの更新を「スクリーニング」するリスクがあるか、またはおそらく更新時にキャッシュをクリアする API を呼び出す際の過度のぎこちなさ。ETag サポートによって提供される負荷の改善に対して、両方の要因を評価する必要があります。
この場合、「銀の弾丸」は存在しないと思います。
編集: あなたのケースでは、ケース A と B の間にほとんど、またはまったく違いはありません。 getUpdatedAt() を実装できるようにするには、更新時間をモデルに保存する必要があります。
この特定のケースでは、動的で明示的な ETag の計算 (ケース A) の方が簡単で保守しやすいと思います。いずれの場合も取得コストが発生し、明示的な計算コストは MD5 計算のコストです。これは非常に高速で、完全に CPU バウンドです。私の意見では、保守性と単純さの利点は圧倒的です。
半関連のメモとして、場合によっては (データベースへの更新が頻繁に行われず、クエリが頻繁に行われる場合)、データベース全体Last-Modified
にグローバルな時間を実装することが有利であり、ほとんど透過的である可能性があります。データベースが変更されていない場合、クエリが何であれ、データベースへのクエリがさまざまなリソースを返す方法はありません。このような状況では、グローバル フラグを簡単かつ迅速に取得できる場所 (データベースである必要はありません) に格納するだけで済みます。例えばLast-Modified
function dbModified() {
touch('.last-update'); // creates the file, or updates its modification time
}
任意のUPDATE/DELETE
コードで。次に、リソースはヘッダーを追加します
function sendModified() {
$tsstring = gmdate('D, d M Y H:i:s ', filemtime('.last-update')) . 'GMT';
Header("Last-Modified: " . $tsstring);
}
そのリソースの変更時間をブラウザに通知します。
If-Modified-Since
次に、永続化レイヤーにアクセスする (または少なくともすべての永続的なリソース アクセスを保存する) ことなく、リソースに対する要求を304 で跳ね返すことができます。記録レベルでの更新時間は必要ありません (しなければなりません):
function ifNotModified() {
// Check out timezone settings. The GMT helps but it's not always the ticket
$ims = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: -1; // This ensures the test will FAIL
if (filemtime('.last-update') <= $ims) {
// The database was never updated after the resource retrieval.
// There's no way the resource may have changed.
exit(Header('HTTP/1.1 304 Not Modified'));
}
}
リソース供給ルートのできるだけ早い段階で ifNotModified() 呼び出しを配置し、リソース出力コードのできるだけ早い段階で sendModified を配置し、リソースに関する限りデータベースが大幅に変更される場合はどこでも dbModified() を配置します (つまり、リソースのコンテンツに影響を与えない限り、アクセス統計をデータベースに記録するときは避けることができますし、おそらく避けるべきです)。