[RESOLU] question organisation bdd pour un forum

Avatar du membre
Eléphanteau du PHP | 31 Messages

24 mai 2022, 20:59

Bonjour, j'ai mis en place un forum et et l'interface est la même qu'ici

l'index liste les forum where catégorie id, et quand on clique sur le viewforum on while la liste des topic where forum id, pour la page viewtopic c'est pareil on while where topic id, avec les clé primaire.

sauf que ça se complique si je veut le last topic, last réponse une image qui indique qu'il y a une nouvelle réponse, nombre de vue etc... et ça sur toutes les pages où c'est utile.

donc je pose la question comment j'organise tout ça dans la base de donnée ? il faudra obligatoire faire des jointures entre quelle table ?

pour le nombre de vue pour tester j'ai fait ça par exemple :

Code : Tout sélectionner

/********** * UPDATE count view si session et id en get ***********/ if(isset($_SESSION['auth']) && isset($match['params']['id'])){ $vu = [intval($match['params']['id'])]; $sql = $db->prepare("UPDATE f_topics SET f_topic_vu = f_topic_vu + 1 WHERE id = ?")->execute($vu); }
faudrait-il pas mettre ça dans une table dédiée plutôt que d'update sur le topic ?

Bonne soirée.

Mammouth du PHP | 1017 Messages

24 mai 2022, 22:04

faudrait-il pas mettre ça dans une table dédiée plutôt que d'update sur le topic ?

Bonne soirée.
Tout dépends du nombre de colonnes déjà existantes dans la table f_topics, si t'en a pas bcp, tu peux le faire sur la même table, si yen bcp, il te faudra commencer à faire plusieurs tables pour séparer.

Une remarque : ne reprends pas le nom de la table pour les noms des colonnes, ça ralonge et ça sert à rien : f_topic_vu peut directement être vues, on comprends aisément.

Pour les images qui indique une nouvelle réponse il te faut faire une nouvelle table nouveaux_messages, avec les colonnes suivantes :

id, id_utilisateur, id_categorie, id_topic

Si quand tu fait une recherche dans cette table et qu'un post y est pas, tu met une image "nouveaux messages", ensuite, quand l'utilisateur va sur le topic, tu ajoute une ligne dans la table nouveaux_messages en renseignant id_utilisateur, id_categorie et id_topic.

C'est une solution.

Avatar du membre
Eléphanteau du PHP | 31 Messages

25 mai 2022, 04:18

Merci de ta réponse

ce que j'ai fait c'est que j'ai créer 2 table topic_track et forum_track

la réflexion c'est que une fois forum track update c'est a dire que l'utilisateur a tout vu parce qu'il s'intéresse a tout lol ou a appuyer sur le bouton tout marquer comme lu.

donc j'ai plus besoin de topic track je peut donc l'effacer seulement pour lui avec son id que j'ai en session comme ça j'ai pas une table surcharger, et dans le cas d'une nouvelle réponse ou topic et bien ça reprend sur topic track, voilà pourquoi j'ai créer 2 tables.

Et la question, où est-ce que je joint ça et dans quelle ordre !? parce que je dois retrouver les vue non vue sur toutes les pages selon ma structure... nivaux requête ça va être du sport a chaque réponse il faudra inscrire read datetime etc... pour le forum topic les réponse.

Code : Tout sélectionner

DROP TABLE IF EXISTS `f_forum_track`; CREATE TABLE IF NOT EXISTS `f_forum_track` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `topic_id` int(11) DEFAULT NULL, `read_topic` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='suivis des vue non vue'; COMMIT;

Code : Tout sélectionner

DROP TABLE IF EXISTS `f_topic_track`; CREATE TABLE IF NOT EXISTS `f_topic_track` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `topic_id` int(11) DEFAULT NULL, `forum_id` int(11) DEFAULT NULL, `read_topic` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='suivis des vue non vue'; COMMIT;
J'ai essayez de m'expliquer au mieux désolé pour le mal de tête :wink: bonne journée.

Mammouth du PHP | 1017 Messages

25 mai 2022, 10:05

La création de 2 tables est pour moi inutile. Une table suffit avec l'id du post (car tous les id de post auront des id unique). Si ya pas d'entrée dans la base de données = post pas vu*. Pas besoin non plus de la colonne read_topic, on s'en fout, tu t'en fout aussi ? Perso quand tu viens sur ce forum, est que tu regarde à quelle heure tu as vue tel ou tel post ? non, car de toute façon ça n'existe pas à mon avis :lol:

Niveau jointure, il faut pas chercher à faire des jointures partout de suite, dans l'idéal c'est déjà de créer une structure, ensuite l'optimisation ;)

* ça te permettra de pas insérer à tous les utilisateur une entrée à chaque nouveau post, imagine toi, avec ta solution, un forum qui compte 200.000 utilisateurs, avec environ 1000 messages par jour = 200.000.000 de lignes à insérer chaque jour rien que pour tester si un message est vu ou non.

Avatar du membre
Eléphanteau du PHP | 31 Messages

28 mai 2022, 23:33

Bonsoir @two3d c'est important le vu non vu sinon on ne sait pas qui a vu quoi et celui a qui a reçu une réponse ne le sais pas non plus,

En vrai j'ai fais ça dans un premier temps : j'ai mes topic listé donc, ensuite je liste aussi mes réponses j'ai left join avec user table ou userid et égal a user_rep_id ces 2 id sont dans la même table réponse j'ai mis une limite a 1.

Et la toutes dernière réponses obtenue je n'affiche que ce don j'ai besoin pour avoir ma dernière réponse et je fait une condition si j'ai pas de réponse je met l'affichage classique l'auteur du topic sinon j'affiche une ligne qui indique qu'on a une réponse par user machin.

Mais là je dois comparé la date dans topic_track si elle est supérieur a la date du dernier topic pour les autres utilisateur qui ne l'ont pas vu, pour ça je dois aussi tenir compte de la dernière réponse.

Code : Tout sélectionner

((f_topic_track.read_topic IS NULL OR f_topic_track.read_topic > f_topic_date)) AS is_not_read
mais je bloque au niveau des comparaison, d'une manière général je me perd toujours dans les requêtes, la date de topic_track sera toujours supérieur a la date du topic ok mais ça ne me dit pas quel utilisateur la vu ?

Bonne soirée.

Mammouth du PHP | 1017 Messages

29 mai 2022, 00:23

Désolé, l'avis d'une autre personne t'aidera peut être :roll:

Avatar du membre
Eléphanteau du PHP | 31 Messages

11 juin 2022, 11:14

Bonjour,

Pour ceux qui cherche comment résoudre le vue non vue c'est pas si évident quand on est un noob comme moi :D

Normalement si vous avez bien créer votre table topic vous avec pris soin de créer une date de création je l'ai mise en datetime

Ensuite au lieu de faire un truc 1 ou 0 c'est pas très pratique puisse que une fois que 1 et égal a 1 on peut plus update a moins d'incrémenté +1 a chaque réponse

Ce que j'ai fais c'est une table séparé

Code : Tout sélectionner

SELECT `id`, `user_id`, `topic_id`, `read_topic` FROM `f_topic_track`
Une fois que l'on poste un topic l'auteur va inséré dans cette table évidement seul ceux qui sont connecter pourront update cette table comme ceci :

Code : Tout sélectionner

if(isset($_SESSION['auth']) && !empty($_SESSION['auth'])){ $userid = intval($_SESSION['auth']->id);//l'id en session de l'utilisateur $get = intval($match['params']['id']); //l'id du topic ici moi j'utilise un routeur pour vous ça sera $_GET['id'] $views = $db->prepare("SELECT id FROM f_topic_track WHERE user_id = ? AND topic_id = ?"); $views->execute([$userid,$get]); $view = $views->fetch(); //on update topic track en fonction de l'utilisateur qui regarde if($view != null){ $u = [$userid,$get]; $db->prepare("UPDATE f_topic_track SET read_topic = NOW() WHERE user_id = ? AND topic_id = ?")->execute($u); }else{ $i = [$userid,$get]; $db->prepare("INSERT INTO f_topic_track SET read_topic = NOW(), user_id = ?, topic_id = ?")->execute($i); } }
Et une fois a l'affichage vous allez faire une jointure et check les différente dates

Code : Tout sélectionner

CASE WHEN read_topic < f_topic_date THEN f_topic_date WHEN read_topic > f_topic_date THEN read_topic END AS read_last
Et a la toutes fin suffit de faire une condition

Code : Tout sélectionner

isset($posts->read_last) && !empty($posts->read_last > $posts->f_topic_date) ? 'vu' : 'non vu' ;
Ensuite a chaque réponse vous allez mettre a jour la date du topic où vous avez répondu

Et voilà vous avez votre système et le plus beau est que vous pouvez faire un bouton tout marquer comme lu et ainsi supprimer cette table topic_track mais seulement de l'utilisateur courant et ça c'est si il a la flemme de tout lire.

Et en bonus :

Si vous voulez ordonner en fonction des dernière réponses a un topic afin qu'il remonté en top vous pouvez faire comme ceci

Code : Tout sélectionner

CASE WHEN f_topic_date < f_topic_reponse_date THEN f_topic_reponse_date WHEN f_topic_date > f_topic_réponse_date THEN f_topic_date ELSE f_topic_date END AS Lastdate
Et vous fait order by Lastdate

Bonne journée !!