Partage
  • Partager sur Facebook
  • Partager sur Twitter

Forum : Accueil.

Comment faire au mieux ?

    31 août 2006 à 1:21:54

    Bonsoir,

    Je suis en train de créer un forum et maintenant que l'interface d'administration est terminée, je peux m'attaquer à celle de visite. Et j'en suis à ... l'accueil ^^ Ce n'est pas tant que j'ai des soucis de code, mais j'aimerais votre avis sur la facon de procéder au mieux pour récupérer les informations dont j'ai besoin. Je m'explique.

    J'ai créé plusieurs tables pour mon forum, que j'ai essayé de définir en troisième forme normale - pour ceux à qui ca cause - :

    forum_categorie(#id_categorie, libelle, ordre)
    forum_section(#id_section, *id_categorie, ordre, libelle, description, *id_fichier)
    forum_topic(#id_topic, *id_section, titre, permanent, ouvert)
    forum_post(#id_post, *id_topic, time_post, contenu, *id_auteur)
    forum_moderateurs(#id_section, #id_moderateur)

    Elles viennent se joindre aux tables déjà existante, dont :

    utilisateurs(#id_utilisateur, login, ..., pseudo, ...)
    fichiers(#id_fichier, *id_utilisateur, url_fichier)

    Le fichier est utilisé comme icone de la section.


    Bon, je vois difficilement quoi dire d'autre pour vous expliquer la situation, donc venons en au fait. J'ai besoin d'énormément de choses pour afficher la page d'accueil et j'aimerais trouver un moyen de le faire en un minimum de requetes, ou du moins de la facon la plus légère qui soit pour le serveur ;o)

    Pour le moment, j'en suis arrivé à ceci :


    // Récupération de la liste des catégories et section du forum.
    "SELECT         c.id_categorie,
                    c.libelle as intitule_cat,
                    c.ordre as ordre_cat,
                    s.id_section,
                    s.libelle as intitule_sec,
                    s.description,
                    s.id_fichier,
                    s.ordre as ordre_sec,
                    f.url_fichier
    FROM       forum_section as s
    LEFT JOIN       forum_categorie as c
    ON            s.id_categorie=c.id_categorie
    LEFT JOIN       fichiers as f
    ON            s.id_fichier = f.id_fichier
    ORDER BY        ordre_cat ASC, ordre_sec ASC"

                                   

    // Récupération de la liste des modérateurs.
    "SELECT         m.id_section,
                    m.id_moderateur,
                    u.pseudo
    FROM       forum_moderation as m
    LEFT JOIN       utilisateurs as u
    ON            m.id_moderateur=u.id_utilisateur
    GROUP BY        m.id_section
    ORDER BY        m.id_moderateur ASC"


                                   
    // Récupération des comptes de sujets.
    "SELECT         COUNT(*) as nb_topic
    FROM        forum_topic
    GROUP BY        id_section"



    // Récupérations du compte de réponses pour la section
    "SELECT         COUNT(*) as nb_post
    FROM        forum_post
    WHERE     id_topic IN (
                            SELECT  id_topic
                            FROM    forum_topic
                            WHERE   id_section=$section
                            )"

                                                                                   

    // Récupération du dernier topic de la section.
    "SELECT         t.id_topic,
                    t.titre,
                    p.id_post,
                    p.time_post,
                    u.id_utilisateur,
                    u.pseudo
    FROM       forum_post as p
    RIGHT JOIN      forum_topic as t
    ON           p.id_topic=t.id_topic
    LEFT JOIN       utilisateurs as u
    ON            p.id_auteur=u.id_utilisateur
    WHERE      p.time_post=(
                            SELECT  MAX(time_post)
                            FROM    forum_post
                            WHERE   id_topic IN (
                                    SELECT  id_topic
                                    FROM    forum_topic
                                    WHERE   id_section=$section))"



    Je peux encore fusionner les deux premières requêtes, et récupérer la liste des modérateurs en même temps que le reste, et je vois assez bien comment stocker les comptes de sujets pour les réutiliser au fur et à mesure, mais cela ne me plait pas encore. Il reste deux requêtes que je dois placer à l'intérieur d'une boucle, et je n'aime pas ca >_<

    Je suis donc venu ici en quête de conseils. Comment vous y prendriez vous ?

    Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      31 août 2006 à 1:29:53

      La réponse est simple: ta question n'as pas lieu d'être :)
      Pour dégager les 3 dernière requete, tu ajoute simplement un champs nbr_sujet, un champs nbr_rep et un champs last_topic_rep dans la table des forum
      nbr_sujet -> nombre de sujet dans le forum
      nbr_rep -> nombre de rep dans le forum
      last_topic_rep -> l'id du topic ou a été poster le derniermessage

      Ensuite pour recuperer le tout, c'est tout con comme requete :D
      • Partager sur Facebook
      • Partager sur Twitter
        31 août 2006 à 1:38:38

        Citation : Folken Laëneck

        plusieurs tables pour mon forum, que j'ai essayé de définir en troisième forme normale


        Ca veut dire pas d'éléments inutiles - ou obtensibles par une autre voie -, ni de redondance. Toutes mes bases sont ainsi jusqu'à maintenant, j'aurais autant aimé qu'il en reste ainsi. ;o)

        De plus, même si ta propoition me simplifierait grandement la vie, elle implique de nombreuses mises à jour lors des enregistrements de sujets, de réponses, etc... Et je ne parle pas des décomptes lors des déplacements de sujets etc ...
        Bref, c'est alléchant, mais pas tant que ca en fait.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          31 août 2006 à 1:42:11

          et pourtant c'est bien plus allechant que tu le crois :)
          Compare un peu le nombre de sujet/reponse poster par rapport au nombre de page vue, il est bien plus faible.
          pour un seul update, tu as facile 5-10 select, donc au final, le moins couteux en terme de perf est l'update.
          Les insertion, simple, avec ta méthode, on peut inserer un sujet en 7 requetes, ce qui est honorable vu tes tables.
          Les suppressions et les deplacement, de 1 à 3 update en fonction de ce que c'est.

          Libre à toi de conserver ton shéma actuel, mais je te le dis tout net, il est moins efficace que ce que je te propose ;)
          • Partager sur Facebook
          • Partager sur Twitter
            31 août 2006 à 1:47:29

            C'est totalement ça, j'ai d'ailleurs appris ça il n'y a pas longtemps ^^
            Si on suit une certaine logique, un post où on répond, c'est logiquement un post qu'on a vu ( arrête :p ).

            Et, on ne répond pas à chaque sujet qu'on voit, donc il est préférable de faire le moins de requetes possible à l'affichage, quit à bourriner pour l'insert et les update ^^
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              31 août 2006 à 1:50:06

              Bourriner, c'ets vite dit :-°
              7 requetes, c'est pas la mort :D
              Même si chaque requete prend 1/50ème de seconde (en général, c'est plutôt un truc genre 1/250 ème ( ou moins ) de seconde pour des requetes si simple :lol: ), 7 requetes, ca ne prend toujours que plus ou moins 0,15 sec, ce qui ets très bine ^^'
              • Partager sur Facebook
              • Partager sur Twitter
                31 août 2006 à 1:56:22

                Citation : Yondaime

                Les insertion, simple, avec ta méthode, on peut inserer un sujet en 7 requetes, ce qui est honorable vu tes tables.



                A la création du topic - le truc le plus complexe dans la partie visite - :
                Une requete sur topic pour le sujet
                Une requete sur post pour le premier message
                Une requete sur section pour updater le nombre de sujet, de post et l'id du dernier post.

                3 contre 2 avec ma méthode. J'ai pas vu le 7 ;o)
                Voilà, c'était pour le plaisir de pinailler :]

                Citation : Yondaime

                Compare un peu le nombre de sujet/reponse poster par rapport au nombre de page vue, il est bien plus faible. Libre à toi de conserver ton shéma actuel, mais je te le dis tout net, il est moins efficace que ce que je te propose ;)



                Hum, il est tard je ne pensais plus que mon site pourrait un jour avoir des visiteurs xD
                Si je tiens à conserver mon shéma actuel, c'est plus pour la beauté du geste en fait. Mais je pense que je vais opter pour quelques disgressions. ;o)

                Merci !

                [Edit] Gné ! o_O Pourquoi il se retrouve là mon poste ? [/Edit]

                [Re-Edit] Je viens d'aller faire un tour sur la doc MySQL, je ne me souvenais plus qu'il était possible de grouper des COUNT et autres avec des sélections normales, je vais aussi essayer de ce côté là - en premier - [/Re-Edit]

                [Re-Re-Edit]

                Bon, j'ai eu une bonne partie de la journée pour bosser dessus et malgré les conditions limites, j'ai réussi à bien avancer sur ma page, au point qu'elle est je pense terminée.

                J'ai finalement trouvé comment obtenir toutes mes informations, sans ajouts sur la troisième forme normale, et en un minimum de requetes. Et surtout, j'ai réussi à sortir toutes les requetes des boucles, ce qui limite désormais strictement leur nombre à trois.

                Je colle ici le code, pour ceux que ca interesse, et j'aimerais si possible vos remarques.

                <?php

                // Page d'accueil du forum.
                echo '<br / >';

                // Récupération de la liste des dernières réponses.
                $reponse=my_query("SELECT       t.id_section,
                                                t.id_topic,
                                                t.titre,
                                                p.id_post,
                                                p.time_post,
                                                p.id_auteur,
                                                u.pseudo
                                FROM        forum_topic as t
                                LEFT JOIN       forum_post as p
                                ON            t.id_topic=p.id_topic
                                LEFT JOIN       utilisateurs as u
                                ON            p.id_auteur=u.id_utilisateur
                                WHERE      p.time_post=(
                                                        SELECT  MAX(p2.time_post)
                                                        FROM    forum_post as p2
                                                        WHERE   p2.id_topic IN (
                                                                SELECT  t2.id_topic
                                                                FROM    forum_topic as t2
                                                                WHERE   t2.id_section=t.id_section))"
                );

                $liste_champs=array("id_section", "id_topic", "id_post", "time_post", "titre""id_auteur", "pseudo");
                if(mysql_num_rows($reponse)!=0)
                        {
                        while($donnees=mysql_fetch_array($reponse))
                                {
                                foreach($liste_champs as $element)
                                        {
                                        $dernieres_reponses[$element][]=$donnees[$element];
                                        }
                                }
                        }
                else
                        {
                        foreach($liste_champs as $element)
                                {
                                $dernieres_reponses[$element][]=0;
                                }
                        }


                // Récupération de la liste des modérateurs.
                $reponse=my_query("SELECT       m.id_section,
                                                m.id_moderateur,
                                                u.pseudo
                                FROM        forum_moderateur as m
                                LEFT JOIN       utilisateurs as u
                                ON            m.id_moderateur=u.id_utilisateur
                                ORDER BY        m.id_section, m.id_moderateur"
                );

                $liste_champs=array("id_section", "id_moderateur", "pseudo");
                if(mysql_num_rows($reponse)!=0)
                        {
                        while($donnees=mysql_fetch_array($reponse))
                                {
                                foreach($liste_champs as $element)
                                        {
                                        $moderateurs[$element][]=$donnees[$element];
                                        }
                                }
                        }
                else
                        {
                        foreach($liste_champs as $element)
                                {
                                $moderateurs[$element][]=0;
                                }
                        }


                // Récupération de la liste des catégories et section du forum.
                $reponse=my_query("SELECT       c.id_categorie,
                                                c.libelle as intitule_cat,
                                                c.ordre as ordre_cat,
                                                s.id_section,
                                                s.libelle as intitule_sec,
                                                s.description,
                                                s.id_fichier,
                                                s.ordre as ordre_sec,
                                                f.url_fichier,
                                                COUNT(DISTINCT t.id_topic) as nb_sujets,
                                                COUNT(p.id_post) as nb_reponses
                                FROM       forum_section as s
                                LEFT JOIN       forum_categorie as c
                                ON            s.id_categorie=c.id_categorie
                                LEFT JOIN       fichiers as f
                                ON            s.id_fichier = f.id_fichier
                                LEFT JOIN       forum_topic as t
                                ON            s.id_section=t.id_section
                                LEFT JOIN       forum_post as p
                                ON            t.id_topic=p.id_topic
                                GROUP BY        s.id_section
                                ORDER BY        ordre_cat ASC, ordre_sec ASC"
                );

                if(mysql_num_rows($reponse)!=0)
                        {                                   
                        // Initialisation des marqueurs de positions et des couleurs.
                        $current_categorie=0;
                        $current_section=0;
                        $couleurs=array("ligne1", "ligne2");
                        $nb_couleur=2;
                        $i=0;
                       
                        // Affichage de l'en-tête du tableau.
                        echo '
                        <table style="width : 100%; margin : auto;">
                                <tr class="ligne4">
                                        <td></td>
                                        <td class="petit">Section</td>
                                        <td class="petit">Sujets</td>
                                        <td class="petit">Réponses</td>
                                        <td class="petit">Dernier message</td>
                                </tr>'
                ;
                        while($donnees=mysql_fetch_array($reponse))
                                {
                                if($donnees['id_categorie']!=$current_categorie)
                                        {
                                        echo '
                                <tr class="ligne3">
                                        <td colspan="5">'
                .stripslashes($donnees['intitule_cat']).'</td>
                                </tr>'
                ;
                                        $current_categorie=$donnees['id_categorie'];
                                        }
                                echo '
                                <tr class="'
                .$couleurs[$i%$nb_couleur].'">
                                        <td width="60px"><img src="'
                .$donnees['url_fichier'].'" width="45px" height="45px" align="middle" / ></td>
                                        <td><strong><a href="'
                .$_SERVER['PHP_SELF'].'?page=4;'.$donnees['id_section'].';0;0;0">'.stripslashes($donnees['intitule_sec']).'</a></strong><br / >
                                        <span class="petit">'
                .stripslashes($donnees['description']).'<br />';
                                        // Affichage des modérateurs.
                                        if(in_array($donnees['id_section'], $moderateurs['id_section']))
                                                {
                                                echo 'Modéré par : <ul class="long_liste">';
                                                foreach($moderateurs['id_section'] as $cle => $element)
                                                        {
                                                        if($element==$donnees['id_section'] AND !empty($moderateurs['pseudo'][$cle]))
                                                                {
                                                                echo '<li class=petit>'.link_profil($moderateurs['id_moderateur'][$cle], $moderateurs['pseudo'][$cle]).'</li>';
                                                                }
                                                        }
                                                echo '</ul>';
                                                }
                                        echo '</td>
                                        <td class="petit" align="center">'
                .$donnees['nb_sujets'].'</td>
                                        <td class="petit" align="center">'
                .$donnees['nb_reponses'].'</td>
                                        <td class="petit" align="center">'
                ;
                                        // Recherche de la dernière réponse.
                                        if(in_array($donnees['id_section'], $dernieres_reponses['id_section']))
                                                {
                                                $key=array_search($donnees['id_section'], $dernieres_reponses['id_section']);
                                                echo '
                                                Le '
                .date('d/m/Y à H:i', $dernieres_reponses['time_post'][$key]).' par '.link_profil($dernieres_reponses['id_auteur'][$key], $dernieres_reponses['pseudo'][$key]).'<br />
                                                Dans "<a href="'
                .$_SERVER['PHP_SELF'].'?page='.$_page[0].';'.$donnees['id_section'].';'.$dernieres_reponses['id_topic'][$key].';0;0" title="Ouvrir '.stripslashes($dernieres_reponses['titre'][$key]).'">'.stripslashes($dernieres_reponses['titre'][$key]).'</a>"';
                                                }
                                        else
                                                {
                                                echo 'Aucun message';
                                                }
                                        echo '</td>
                                </tr>'
                ;
                                $i++;
                                }
                        echo '
                        </table>'
                ;
                        }
                else
                        {
                        echo '<center>Aucune section n\'a encore été ouverte dans ce forum.</center><br />';
                        }

                ?>
                • Partager sur Facebook
                • Partager sur Twitter

                Forum : Accueil.

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown