Structure bdd messagerie

WRInaute impliqué
Bonjour,
J'ai un site avec des utilisateurs, je veux créer une messagerie affin que les utilisateurs puissent se contacter avec un simple message. J'ai donc créé une table comme ceci :

id --------- idposteur -------------- idrecepteur----------- message ------------- date

avec :

idposteur : c'est l'ID de la personne qui a envoyé le message,
idrecepteur : la personne qui a recu le message,

Maintenant par exemple quand jozef ouvre la page mesmessage, je dois afficher les personnes avec qui il a communiqué et c'est la le problème, je vaiss avoir toute la liste des message alors que je veux juste afficher les personne avec qui il a communiqué.

Bon, si je dois penser plus pour trouver une solution pour l'affichage je souhaite avoir votre avie sur la structure et si vous avez une structure bien améliorée.

merci
 
WRInaute impliqué
tu fais 2 requetes, une qui retourne les infos des personnes, avec idposteur=iddejozef, l'autre qui retourne les infos des personnes, avec idrecepteur=iddejozef
 
WRInaute impliqué
jusqu'ici tout va bien mais imagine si :
- Jozef a envoyé 10 message à MOI
- Moi a envoyé 8 messages à Jozef

- Moi a envoyé 3 message à Christine
-Christine a envoyé 7 messages à moi

Dans la page mes messages j'aurais 2 div, le premier contient un lien vers ma discussion avec Jozef et le deuxième div contient ma discussion avec Christine.

mais avec ton code ça m'affiche plusieurs div chaque div contient un message (total nombre de messages échangé) alors que c'est pas une page d'affichage de message mais de discussions globale avec les personnes, une fois je clique sur une discussion avec Christine par exemple là j'aurais mes messages avec christine, là je gère
 
WRInaute accro
mais avec ton code ça m'affiche plusieurs div chaque div contient un message
Pas forcement > GROUP BY ou DISTINCT.

En imaginant que tu veuille deux div :

* Une pour les conversations où tu dois répondre
le message d'id le plus élevé avec id utilisateur == idrecepteur
genre : select idrecepteur from table where idrecepteur = (ton id) group by idposteur order by date

* Une autre pour les conversations ou tu as répondu
le message de l'id le plus élevé avec id utilisateur == idposteur
genre : select idrecepteur from table where idposter = (ton id) group by idrecepteur order by date
 
WRInaute impliqué
Ah merci zeb je connais pas le group by, et si je veux afficher les deux * dans le même div genre un div pour la discusssion entre idposteur et MOI

Genre : select idposteur and idrecepteur from table where idposteur =(mon id) and idrecepteur == (mon id) group by idposteur and idrecepteur

Car il y a 3 cas :
1- on ma envoyé un message et j'ai pas répondu, dans ce cas (mon id) existe que dans idrecepteur
2- j'ai envoyé un message et on ma pas répondu, dans ce cas (mon id) existe que dans idposteur
3- on a dicuté ensemble (passage de messages entre les deux) (dans ce cas (mon id) existe dans idposteur et idrecepteur
 
WRInaute impliqué
ousps ça ne marche pas, voila j'explique clairement :

148645Sanstitre.png


voila je veux regrouper tout ce qui est en rouge : idsender = (mon id) and idrecver = (mon id)
Ce qui va me donner une seule ligne :)

Une idée ?

merci
 
WRInaute passionné
Bonjour,

je travailles dans un autre environnement de BDD (4D), mais il me semble que ta structure ne correspond pas a ce que tu aimerais avoir.

Si j'ai bien compris, tu aimerais recréer une ID de conversation en faisant des recherches et rapprochement par id de message(en fait par idsender et idrecever). Quelques soit 'id ou le champ, tu cherche plutot à faire un regroupement par "sujet" (ou conversation) en somme, mais c'est manquant...

Tu ne gagnerais pas en simplicité en ajoutant un champ ID_conversation? Ainsi, que tu soit seul (émeteur ou receveur), deux, trois ou 4 etc … ca simplifierais non? De plus, à la longue, il te faudra limiter de toute manière l'affichage, et ca risque d'être difficile de t'y retrouver dans tous les messages, avec un tel ou un tel, le sujet, etc...

Avec se nouveau champ, tu regroupe d'un coup l'ensemble. Une selection vers tableau et en 1 milliseconde, tu as le détail classé par date.

C'est juste une idée comme ça en parcourant le sujet ...
 
WRInaute passionné
Dans une table relationnelle, l'idéal serait d'avoir 2 tables

Table_conversation ;
-> champ_ID (numérique)
-> sujet (texte) (on peu incrémenter ce champ par exemple de la derniere réponse, ou d'un sujet de son choix)
->date_crea (date)
->date_modif (date)
->cloture (booleen)
->priorite


Table_message
->ID
->id_conversation (lien)
->id_sender
->id_receipt
->date (selon le format fusionnable avec H)
->heure
->nom_sender
->nom_recept
->lu_part_recept (booleen)
->Date_H_lu
->message
->priorite (booleen)

Dans mon environnement ca donne:

Code:
CHERCHER([Table_conversation]; [Table_conversation]cloture=faux)
TRIER([Table_conversation]priorite;>;[Table_conversation]date_modif;<)

puis gérer l'affichage avec une boucle par exemple, mais il y a plusieurs manière de faire cela

pour faire simple (toujours dans mon environnement)

Code:
//Déclarations
TABLEAU TEXTE($Tab_sujet;0)
TABLEAU DATE($Tab_date_modif;0)
$RC:=caractère(retour_chariot)
//
// on cree 2 tableaux selon la sélection 
SELECTION VERS TABLEAU([Table_conversation]sujet;$Tab_sujet;[Table_conversation]date_modif;$Tab_date_modif)

$montexte_final:="DATE | SUJET | DERNIER_MESSAGE"+$RC

BOUCLE($i;1;taille tableau($Tab_date_modif))
CHERCHER([Table_message];[Table_message]id_conversation=[Table_conversation]champ_ID)
TRIER([Table_message]Date;<) // donc on est positioné sur le message le plus récent
SI([Table_message]lu_part_recept=vrai)
montexte_final:= montexte_final+chaine($Tab_date_modif{$i})+" | "+$Tab_sujet{$i}+" | "+[Table_message]message+$RC
SINON
montexte_final:= montexte_final+chaine($Tab_date_modif{$i})+" | "+$Tab_sujet{$i}+" | <strong>"+[Table_message]message+"</strong>"+$RC
FIN DE SI
FIN DE BOUCLE

tu peux entourer le champ "[Table_message]message" d'un lien qui va par exemple t'ouvrir un pop-up avec la liste triée de tous les messages de cette conversation. Dans cette approche, tu as déjà la dernière réponse, elle peut te suffire.

C'est d'ailleurs un peu comme un forum, en simplifié ...

C'est une idée ...
 
WRInaute impliqué
c'est très bien expliqué merci beaucoup, une nouvelle table facilite beaucoup le tavail certes, mais les autres sites utilisent une seule table (tel que j'ai montré en haut), le seul hic c'est d'afficher la lite des discussions :(
 
WRInaute impliqué
non j'ai pas parlé de la suppression j'ai mon astuce pour la suppression, je vais faire comme facebook le message sera caché pour le premier utilisateur s'il le supprime si le deuxième supprime le meme message il sera complètemnet supprimé.
 
WRInaute accro
Une piste qui marche pour un utilisateur donné (éventuellement l'id du gars connecté)
Soit la table :
737752740.jpg


Code:
SELECT recever, GROUP_CONCAT(id) as convers FROM `aaa_test` 
WHERE (sender = 1 OR recever = 1) GROUP BY (sender*recever)

L'idée c'est de sélectionner les messages ou l'utilisateur est l’émetteur ou le destinateur (id=1 ci dessus) en groupant sur un critère unique pour une conversation (ici le produit de leur id respectif qui ne peut être que unique pour les convers d'un utilisateur donnée). de plus en agrégeant les id tu as accès a l'ensemble des messages d'une conversation entre deux personnes (ici c'est formalisé par la collone "convers" qui est le fruit de "GROUP_CONCAT(id) as convers").

exemple pour l'utilisateur 1
2102142500.jpg

exemple pour l'utilisateur 3
327330000.jpg
 
WRInaute impliqué
Ah merci beaucoup zeb c'est plus claire merci pour votre temps :( j'ai donc utilisé ceci et ça marche parfaitement mais j'ai pas trop testé :

Code:
$ens= "SELECT * from message where idrecever='$id' or idsender='$id' group by (idsender * idrecever) order by id desc";
[code]

vous pensez que ça fait l'affaire ?
 
WRInaute accro
oui ça fonctionne sauf que tu récupère des trucs inutiles comme id et message qui ne correspondent a rien de pertinent pour une conversation. Group_concat(id) lui en revanche te donne tous les id de message d'une convers ça peut être utile avec un explode()
 
WRInaute passionné
Attention GROUP_CONCAT est bridée par défaut à 1024 caractères (cf group_concat_max_len), et sur le principe aura toujours une limitation en taille. Donc quand on s'en sert, il faut être absolument certain qu'on récupérera tous les enregistrements qu'on voulait.
 
WRInaute impliqué
Moi je veux juste récupérer 200 caractères du dernier message @Bool :) merci pour l'information.

Zeb oui ça va m'aider je vais l'utiliser, mais une question, Group_Contact elle regroupe les messages et met une virgule à coté de chaque message, si on utilise explode, imagine qu'un message contient déjà une virgule ?
 
WRInaute impliqué
Dernier truc que je vous demande et je vous remercie beaucoup, c'est comment récupérer le début d'une chaine de caractère avant la virgule ','

Merci
 
WRInaute accro
GROUP_CONCAT est pas trop adapté a l'agrégation de contenu texte en fait, pour le point que tu soulève (présence de virgules) et aussi pour la remarque que fait bool sur la taille limite du blob retourné.

Quoi qu'il en soit essaye ta requête sans le GROUP_CONCAT et vérifie que c'est bien le dernier message qui est retourné et si ce n'est pas le cas ajoute une order by pour assurer le coup.

Pour ne prendre que X caractères dans une chaine utilise substr() en php ou directement dans la requêtes SQL.
 
Discussions similaires
Haut