Bonjour !

Dans le cadre du développement de mon site internet, je suis confronté à du SQL qui dépasse mon niveau (je me suis plus ou moins arrêté à ce qu'on trouve sur le site dans les tutoriels SQL "officiels").

Mon objectif est d'arriver à une messagerie multi-utilisateurs.
Mon problème est de savoir comment afficher les messages de l'utilisateur (page d'index de la messagerie), ainsi que les participants avec les informations qui vont avec (pseudo, date de dernière connexion etc...).

Pour ça, j'ai d'ores et déjà quelque chose, mais j'ai peur que ça fonctionne mal en cas de grande quantité... En gros, j'utilise trois tables :

- titres_messages_personnels : contient l'id du titre, le nom, etc...

- participants_messages_personnels : indexée sur deux champs (id_titre, id_membre) c'est une table de passage entre les titres et les membres pour savoir qui participe aux mp

- messages_personnels : contient les messages en question (liée à titres_messages_personnels par le champ "id_titre"

Ainsi, pour l'affichage, je fais une première requête qui me sert pour compter les messages du membre et pour écrire une liste (de la forme 1,2,3,4,5,6... variable $ids_titres) qui contient les id des titres.

Ensuite, c'est la requête à optimiser que voici :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
SELECT GROUP_CONCAT(membres.pseudo ORDER BY membres.pseudo SEPARATOR '\n') AS pseudos_participants, GROUP_CONCAT(membres.id ORDER BY membres.pseudo SEPARATOR '\n') AS ids_participants, GROUP_CONCAT(participants_messages_personnels.supprime ORDER BY membres.pseudo SEPARATOR '\n') AS supprimes_participants, GROUP_CONCAT(participants_messages_personnels.lu ORDER BY membres.pseudo SEPARATOR '\n') AS lus_participants, GROUP_CONCAT(membres.timestamp_connexion ORDER BY membres.pseudo SEPARATOR '\n') AS timestamps_connexion_participants,
			titres_messages_personnels.titre, titres_messages_personnels.description, titres_messages_personnels.nombre_messages, titres_messages_personnels.id, titres_messages_personnels.timestamp_modification, titres_messages_personnels.timestamp_creation,
			dernier_message.id AS id_dernier_message,
			dernier_auteur.pseudo AS pseudo_dernier_auteur, dernier_auteur.id AS id_dernier_auteur
			FROM participants_messages_personnels
			LEFT JOIN membres ON participants_messages_personnels.id_membre=membres.id
			LEFT JOIN titres_messages_personnels ON participants_messages_personnels.id_titre=titres_messages_personnels.id
			LEFT JOIN messages_personnels dernier_message ON titres_messages_personnels.id_dernier_message = dernier_message.id
			LEFT JOIN membres dernier_auteur ON dernier_message.id_auteur = dernier_auteur.id
			WHERE participants_messages_personnels.id_titre IN (".$ids_titres.") AND membres.id != 0
			GROUP BY participants_messages_personnels.id_titre
			ORDER BY titres_messages_personnels.timestamp_modification DESC
Voilà pour la structure des tables :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
--
-- Structure de la table `messages_personnels`
--
 
CREATE TABLE IF NOT EXISTS `messages_personnels` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_auteur` int(11) NOT NULL,
  `id_titre` int(11) NOT NULL,
  `timestamp_creation` int(11) NOT NULL,
  `signature` varchar(1) NOT NULL,
  `message` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=36 ;
 
-- --------------------------------------------------------
 
--
-- Structure de la table `participants_messages_personnels`
--
 
CREATE TABLE IF NOT EXISTS `participants_messages_personnels` (
  `id_titre` int(11) NOT NULL,
  `id_membre` int(11) NOT NULL,
  `supprime` int(11) NOT NULL,
  `lu` varchar(1) NOT NULL,
  KEY `id_titre` (`id_titre`,`id_membre`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
-- --------------------------------------------------------
 
--
-- Structure de la table `titres_messages_personnels`
--
 
CREATE TABLE IF NOT EXISTS `titres_messages_personnels` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titre` text NOT NULL,
  `description` text NOT NULL,
  `id_maitre` int(11) NOT NULL,
  `timestamp_creation` int(11) NOT NULL,
  `timestamp_modification` int(11) NOT NULL,
  `nombre_messages` tinyint(4) NOT NULL,
  `id_dernier_message` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
Il y aussi la table membres, mais elle n'est pas intéressante ici (id, pseudo, timestamp_connexion suffisent).

Voilà pour un jeu d'insertion :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
INSERT INTO `messages_personnels` (`id`, `id_auteur`, `id_titre`, `timestamp_creation`, `signature`, `message`) VALUES
(1, 1, 1, 1242317127, '1', 'Message de test et démonstration.');
 
 
INSERT INTO `participants_messages_personnels` (`id_titre`, `id_membre`, `supprime`, `lu`) VALUES
(1, 1, 0, '1'),
(1, 10, 0, '0'),
(1, 14, 0, '1'),
(1, 15, 0, '1'),
(1, 16, 0, '0'),
(1, 17, 0, '0');
 
INSERT INTO `titres_messages_personnels` (`id`, `titre`, `description`, `id_maitre`, `timestamp_creation`, `timestamp_modification`, `nombre_messages`, `id_dernier_message`) VALUES
(1, 'Message', '', 1, 1242317127, 1242570245, 12, 18);
Seriez-vous capables de me dire comment je peux l'optimiser ? Parce qu'en cas de dizaines de milliers de messages persos (et ce sera le cas), il pourra y avoir de gros ralentissements...

Merci d'avance et bonne journée !