Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD
PHP & SGBD Forum d'entraide sur les SGBD avec PHP. Avant de poster : FAQ BDD, toutes les FAQ PHP, cours BDD et sources BDD
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 15/02/2007, 11h33   #1
Invité de passage
 
Inscription : février 2007
Messages : 4
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 4
Points : 0
Points : 0
Par défaut [SQL] Pb: Forum en arborescence

Bonjour a tous,

Je suis actuellement stagière dans le milieu informatique et on m'a demandé de réaliser un forum assez spécial, un forum en arborescence (et oui maintenant on prend les stagiaires pour des techniciens de chez usenet) qui doit se présenter sous cette forme:

Artcile
|
|_Reponse_article
| |
| |_Reponse_de_la_Reponse_article
| |
| |_Reponse_de_la_Reponse_article
| --|
| --|_Reponse_de_la_Reponse_de_la_Reponse_article...(etc)
|
|_Reponse_article

Seul le sujet est affiché dans l'arboréscence car il faudra cliquer dessus pour afficher le message en entier. Pour réaliser ça j'ai pensé à une table avec un système de chaîne et d'articles enfants ou parents. Voici ma table pour les article.

CREATE TABLE `post` (
`id_post` int(11) NOT NULL auto_increment,
`corps_post` text NOT NULL,

`sujet_post` text NOT NULL, -- <-- c'est ça qu'il faut afficher

`auteur_post` varchar(50) NOT NULL default 'Inconnu',

`main` varchar(6) NOT NULL default 'parent', -- <-- indique si le post est parent ou enfant

`chain` int(11) NOT NULL default '0', -- <-- permet de connaître à quel post le message est relié.

`id_membre` int(11) NOT NULL default '0',
`date_post` datetime NOT NULL default '2000-01-01 00:00:00',
PRIMARY KEY (`id_post`)
)


Mon gros soucis est que je n'arrive absouluement pas a réaliser cet affichage puisqu'il est possible de chainé un message une infinité de fois. Je suis complétement perdu au niveau du code ! Si quelqu'un peut m'aider je lui serais vraiment très reconnaissante

Grand merci,

Eleison
Eleison est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2007, 12h00   #2
Membre émérite
 
Avatar de Yobs
 
Inscription : avril 2004
Messages : 675
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2004
Messages : 675
Points : 808
Points : 808
Envoyer un message via MSN à Yobs
Au niveau conceptuel, je me serais orienter plutot sur une structure à 2 tables (posts pour les parents et comments pour les enfants).

Pour le code, il te suffirait de faire des requetes récupérant chaque poste et
une autre récupérant les comments associé.

Pour l'affichage, tu as plusierus solutions, utiliser les "tree" ( par exemple celui sur http://www.dhtmlgoodies.com ) , utiliser les balises <dl>, <dd>, <dt> ...
__________________
Chaque problème a une solution, mais il est plus facile de répondre si le problème est correctement renseignés
Yobs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2007, 01h43   #3
Membre éprouvé
 
Avatar de goodpz
 
Inscription : février 2007
Messages : 475
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 475
Points : 474
Points : 474
La solution la plus simple c'est que chaque post ait un champ "parent" qui contient l'id du post parent. Le post racine lui aurait un champ "parent" null. Il n'y a donc pas de différentiation entre un parent (noeud) et une feuille au niveau des informations contenues dans un row de la table.

Pour afficher l'arbre, il faut procéder par récursion:
- Trouve l'id du row qui a un parent null (le post racine)
--- Trouve tous les rows qui ont pour parent l'id que tu viens de trouver
----- Pour chaque rows trouvés, procède de la même manière pour trouver les fils
------- Ainsi de suite

L'avantage de cette méthode c'est que le schema de la table est simple et immédiat en update/delete

Le désavantage c'est la récursion qui a tendance à bouffer de la mémoire et le nombre de requêtes sql.

Il y a une autre méthode qui permet d'éliminer la récursion et qui permet aussi de tout récupérer dans l'ordre en une seule requête: les arbres préordonnés. La contrepartie c'est que le schema de la table est un peu plus complexe. En plus d'un champ "parent" qui contient l'id du post parent, il faut ajouter les champs "left" et "right" qui indexent les rows en depth-first search.

Un exemple: les valeurs de "left" et "right" sont les nombres à gauche et à droite de chaque Article. Regarde bien comment ces nombres sont distribués pour "entourer" chaque Article dans le sens de la profondeur

Code :
1
2
3
4
5
6
7
 
1 Article 12
  2 Article 7
    3 Article 4
    5 Article 6
  8 Article 11
    9 Article 10
Rapatrier tout l'arbre dans l'ordre ça revient à faire ce genre de chose:
SELECT * FROM table ORDER BY left ASC;

Rapatrier juste une sous branche:
SELECT * FROM table WHERE left BETWEEN 2 AND 7 ORDER BY left ASC;

Il faut bien sûr prendre plus de précautions quand vient le moment d'ajouter et/ou enlever des rows dans la table. Il faudra mettre à jour toutes les valeurs des "left" et "right" concernés. Généralement, ça revient à ajouter 2 à certaines de ces colonnes.

Par exemple si tu veux ajouter un fils à "3 Article 4", il faut:

UPDATE table SET right=right+2 WHERE right>3;
UPDATE table SET left=left+2 WHERE left>3;
Ajouter ensuite le nouvel Article en mettant left=4 et right=5

Maintenant, pour ce qui est de l'affichage (quelque soit la méthode), c'est assez simple si on met de coté une représentation avec des branches relièes entre elles (comme un treeview). Dans un tel cas, c'est plus simple encore une fois avec la méthode des arbres ordonnés car mettre une barre verticale (portion de branche) à une position p sur la ligne d'un Article A ça revient à dire qu'il existe un Article B de position p plus bas dans l'arbre dont le parent est un des ancêtres de A (oof, je ne sais pas si je me fait bien comprendre là ; )
goodpz est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h00.


 
 
 
 
Partenaires

Hébergement Web