2

スレッド用、コメント用、および 2 つを接続する 1 つずつ、3 つの正規化されたテーブルがあるとします。

スレッド内のコメント数を表示したいのですが、それには特定のスレッドに属するすべてのコメントを見つけることが含まれます。

明らかに、ページを表示するたびにこのクエリを実行したくないので、コメントの数をスレッドにキャッシュする必要があります。私の2つのオプション(私が見ているように)は次のとおりです。

  1. number_comments 行をスレッド テーブルに追加し、コメントを追加または削除するたびに更新します。

  2. 値をキャッシュするように mysql に指示するか、APC / memchached などを使用して、値をメモリにキャッシュします。

それぞれの長所/短所は何ですか?

最初のものは単純で、パフォーマンスが少し低いと思いますが、冗長性があり、ストレージはメモリよりもはるかに安価ですが、「動的」で常に変化する値でデータベースを台無しにします (また、私がコメントの「賛成票」を保存する必要があるため、この質問は複数の「動的」値に適用されます)。

2 つ目はパフォーマンスが向上しますが、新しいテクノロジが導入され、多くのことをキャッシュするためだけに関連付ける必要があります。

このプロジェクトのユーザー数は比較的少ないですが、訪問者の多いサイトよりもどちらが好ましいかを知りたいです(たとえば、Facebookはコメント数をどのように保存しますか[データベースとメモリの両方で推測しています])。

4

2 に答える 2

1

Donald Knuth からの次の引用を覚えておいてください。

時期尚早の最適化は諸悪の根源です。

キャッシング、またはこの場合の「データベースの非正規化」は完全に有効なオプションだと思いますが、「通常の」アプローチが適切でなくなった場合に検討するのが最適なオプションです。

あなたは「明らかに」、すべてのページ ビューでコメント数を取得するために余分なクエリを実行したくないと言っていますが、実際にはそれほど明白ではありません。データベースが適切に設定されていれば、thread_idコメント テーブルのフィールド (またはフィールドの呼び方) に既にインデックスが設定されているはずです。インデックス付きフィールドに基づいてクエリを実行しても、特にクエリCOUNT()がスレッドの膨大なリストではなく、生成されたフィールドのみを返す場合、実際には多くのオーバーヘッドはありません。そのクエリを実行して完了する方が簡単だと思います。

とはいえ、パフォーマンス上の理由からデータベースを非正規化する必要がある場合は、データベースを非正規化する価値があります。その場合、comments_count新しいレコードがテーブルに追加または削除されるたびにインクリメントされるスレッド テーブルにフィールドを追加します。テーブルがアクティブ/削除された状態を追跡するかどうかに応じて、クエリINSERTDELETEクエリを囲む余分なコードを追加することを覚えておく必要があります。UPDATEcomments

繰り返しますが、これはほとんどの場合、時期尚早の最適化です。自問する必要がある質問は、「このサイトは非常に混雑している/負荷が非常に高いため、計算フィールドを管理する複雑さが増しても、簡単なCOUNT()クエリを実行するよりもコストがかからないか?」ということです。そうである場合は、必ず非正規化ルートを選択してください。ただし、最初に選択するべきではないでしょう。

于 2013-01-18T02:54:38.540 に答える
0

number_comments フィールドを追加するのは適切ではないと思います。1 つは、これを最新の状態に保つのが面倒で、追加のコードが必要になることです。また、データベースに冗長性を追加します。

これにより、2 つの選択肢が残ります。ページの上部で、各 ID のカウントを取得するクエリを実行できます (これは、スレッドごとに 1 つではなく、1 つのクエリで可能である必要があります)。これは簡単で、遅すぎてはいけません。

パフォーマンスが問題である、または問題になる可能性があり、これがボトルネックであると確信している場合は、APC と Memcache の両方が適しています。これにより新しいテクノロジーが追加されますが、PHP でこれをセットアップするのは非常に簡単であり、将来の他のアイテムのキャッシュがより簡単になることを意味します。

于 2013-01-18T02:00:43.717 に答える