2009-06-27 25 views
0

私は簡単なフォーラムを構築しようとしています。トピックのリスト(返信がない場合)または最新の回答のいずれかの日付の降順で表示されます。ここでDB構造です:参加のヘルプが必要

トピック
id, subject, date, poster

投稿
id, topic_id, message, date, poster

フォーラム自体は、以下のヘッダを持つHTMLテーブルで構成されます:
Topic | Last Post | Replies

クエリまたはq ueriesはそのような構造を生成するように見えますか?私はそれがクロス結合を含むと思っていましたが、確信が持てません...事前に感謝します。

答えて

1

もちろんこれについてクエリを行うことはできますが、トピックテーブルの[返信]と[最終投稿]フィールドに作成し、新しい投稿ごとに更新することをおすすめします。それは本当にあなたのデータベーススピードを、今ではなく、あなたが何千ものトピックを持っている時間に改善することができます。

+0

あなたはおそらく正しいでしょう。ありがとう! –

+0

慎重なベンチマークの前に非正規化を行う必要があることは、時期尚早の最適化の例です。 –

0
SELECT * 
FROM 
    `Topics`, 
    (
     SELECT *, COUNT(*) AS `replies` 
     FROM `Posts` 
     GROUP BY `Posts`.`topic_id` 
     ORDER BY `Posts`.`date` DESC 
    ) AS `TopicPosts` 
WHERE `Topics`.`id` = `TopicPosts`.`topic_id` 
ORDER BY `Posts`.`date` DESC 

でもこの作品は、「べき」、またはほとんどそうでない場合には動作しますが、私は他のポスターに同意する、それが理由のすべての種類のためのトピックの表に、このデータを保存するために、おそらく良いでしょう、それがデータの複製である場合。

+0

私の頭の上から外して... –

+0

ありがとう。私はThinkerが言ったように私はやりますが、私はこのコードを保存します。 –

0

フォーラム自体は、次のヘッダーと HTMLのテーブルで構成されます:「最後の投稿は」日付であることを意味する場合
Topic | Last Post | Replies

、それは簡単です。

SELECT 
    t.id, 
    t.subject, 
    MAX(p.date) AS last_post, 
    COUNT(p.id) AS count_replies 
FROM 
    Topics t 
    INNER JOIN Posts p ON p.topic_id = t.id 
GROUP BY 
    t.id, 
    t.subject 

あなたは他のものはそのidまたはposterのように、最後のポストの日付と一緒に表示したい場合は、それはもう少し複雑になります。

SELECT 
    t.id, 
    t.subject, 
    aggregated.reply_count, 
    aggregated.distinct_posters, 
    last_post.id, 
    last_post.date, 
    last_post.poster 
FROM 
    Topics t 
    INNER JOIN (
    SELECT topic_id, 
      MAX(p.date) AS last_date, 
      COUNT(p.id) AS reply_count, 
      COUNT(DISTINCT poster) AS distinct_posters 
    FROM  Posts 
    GROUP BY topic_id 
) AS aggregated ON aggregated.topic_id = t.id 
    INNER JOIN Posts AS last_post ON p.date = aggregated.last_date 

例として、このアプローチをどこに拡張できるかを示すトピックとして、別のポスターの数を追加しました。

クエリは、1つのトピック内に2つの投稿が同じ日付を持つことができないという仮定に基づいています。これが起こることが予想される場合は、それを考慮に入れてクエリを変更する必要があります。