9

次の問題の最適な解決策を見つけようとしています。データベース(postgresベース)、その中のトリガーとカウンターのシステムを設計する必要があります。これにより、情報を効率的にクエリ、更新、および保存するシステムが形成されます。 「ページに表示されている各記事 (またはブログ エントリなど) にどれだけの未読コメントが存在するか」。

頭に浮かぶすべてのソリューションには、クエリ、保存、または更新部分のいずれかで、いくつかの重大な欠点があります。つまり、必要なストレージが多すぎる、更新が多すぎる、クエリのコストが高すぎるなどです。

あなたの経験はどうですか?この種の問題に対して、すでに形成された優れた解決策があるのではないでしょうか?

4

5 に答える 5

9

スキーマをできるだけ単純に保つため、クエリは可能な限り単純になります。これは通常、ストレージ要件も最も低くなります。もちろん、このクエリをサポートするようにインデックスを設定してください。

次のステップ: パフォーマンスを測定してください! 「測定することは知ることです。」応答時間は?サーバーの負荷は?パフォーマンスが許容範囲内である限り、スキーマとクエリをシンプルに保ちます。保守性が絶対に必要でない場合は、保守性を犠牲にしないでください。後継者は後で感謝します。

パフォーマンスが本当に問題である場合は、アプリケーションに使用しているフレームワークのキャッシュ機能を調べてください。クエリを実行しない方が、最適化されたクエリを実行するよりも常に高速です。

于 2009-01-17T09:57:58.703 に答える
4

リソース エンベロープ内でうまくいかない場合は、ユーザー エクスペリエンスを微調整する必要があるかもしれません。おそらく、スレッドへの最後のアクセスの日付を保存するだけで十分です。

于 2009-01-17T10:00:20.880 に答える
4

典型的な正規化されたアプローチでは、非効率的なクエリが残るとは思いません。PKを持つテーブルとarticle_commentsPK(article_id, comment_id)を持つ別のテーブルがあるとします。ページにリストされている記事ごとに、次のことを行う必要があります。comments_seen_by_user(user_id, article_id, comment_id)

SELECT count(*) FROM article_comments ac
WHERE article_id = ?                -- Parameter
AND NOT EXISTS (
    SELECT 1 FROM comments_seen_by_user csbu
    WHERE csbu.user_id = ?          -- Parameter
    AND   csbu.article_id = ac.article_id
    AND   csbu.comment_id = ac.comment_id
)

ページに 20 個の記事を表示する場合、上記のクエリを 20 回実行し、各実行でインデックスを使用して から 10 ~ 20 行を抽出しますarticle_comments。サブクエリ テストは、 の別のインデックス スキャンcomments_seen_by_userなので、すべて特定のページを表示するために 20 * (20 * 2) = 800 回のインデックス付きルックアップを実行する必要があります。これは、最新の DB にとっては簡単なことです。そして、私はおそらく、PostgreSQL が見つける可能性のあるさらに優れたクエリ プランを見落としています。

これを試してみて、パフォーマンスが不足していることがわかりましたか? もしそうなら、私の最初の推測では、あなたはしばらく教育を受けていないでしょうVACUUM. そうでなければ、1 ページあたりの記事数、または 1 記事あたりのコメント数の見積もりが間違っていたに違いありません。その場合は、詳細を更新してください。

于 2009-01-17T10:50:14.040 に答える
1

私は j_random_hacker の答えを 2 番目にします。また、PostgreSQL では 3 次元 (および程度は低いが 2 次元) のインデックスは依然として遅いため、避けるようにしてください。

user_id、comment_id 値のテーブルを回避して、読み取りコメントに関する情報を格納する良い方法はありません。一意のインデックスがあることを確認してください。このようなテーブルの数千万行は、インデックスをメモリに保持できる限り、PostgreSQL にとってまったく問題ありません。システム テーブルへのクエリを使用して、インデックス サイズ (ディスク上の 8KB ページの数) を追跡できます。

select relname,relpages from pg_class where relname='comments_seen_by_user_pkey';
于 2009-01-17T11:05:38.237 に答える
0

正規化されたアプローチを採用し、それがうまくいくかどうかを確認することに同意します。通常、私はすべきです。ただし、'comment' テーブルで INSERT トリガーを使用することもできます。これにより、ベース (記事) テーブルのコメント カウンターが更新されます。これは、この Web サイトの使用プロファイルによって異なります。コメントがほとんど読まれる場合 (コメントを追加する場合と比較して)、トリガー ベースのアプローチのオーバーヘッドはすぐに償却されます。それ以外の場合、コメントの負荷が高いサイトの場合、パフォーマンスが低下する可能性があります.

シンプルで正規化されたテーブル構造を採用し、合理的な使用プロファイルがある場合は、後で他の最適化を追加します。

于 2009-01-17T12:01:25.613 に答える