IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Création d'une table du nombre de post d'un membre et par forum


Sujet :

Requêtes MySQL

  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut Création d'une table du nombre de post d'un membre et par forum
    Bonjour,

    Je désire toujours dans l'application d'un forum pouvoir faire une table qui contiendrait le nombre de messages posté par un membre et ceci pour chaque forum.

    A 1ère vue, ça me donnerait une table de ce style :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE MEMBRE_POST(
    	membre_id INT(5) UNSIGNED NOT NULL,
    	forum_id INT(2) UNSIGNED NOT NULL,
    	nb_post INT(5) UNSIGNED DEFAULT 0,
    	INDEX(membre_id, forum_id)
    	FOREIGN KEY(membre_id) REFERENCES MEMBRE(membre_id) ON UPDATE CASCADE ON DELETE CASCADE,
    	FOREIGN KEY(forum_id) REFERENCES F_FORUM(forum_id) ON UPDATE CASCADE ON DELETE RESTRICT
    ) TYPE = INNODB;

    Donc autant de lignes pour un seul membre qu'il n'y a de forum.
    Mais ça me pose problème car je suis contraint de vérifier avec un UPDATE si le membre a déjà posté dans le forum, donc une requête supplémentaire, pas top.

    J'ai donc pensé à une table de même type, sauf que chaque forum sera représenté par une colonne avec pour défaut 0, une nouvelle ligne sera créée dès l'inscription du membre, un ALTER TABLE serait effectué en cas d'ajout d'un nouveau forum.
    Cela me permettrait en faisant ça, un UPDATE sans SELECT préalable.

    Seulement, et oui, il faudrait que je stocke l'id du forum dans le nom de la colonne, et ça c'est pas tip-top non plus...

    Bref, j'arrive pas à trouver une solution correcte tout en prenant en compte que je ne doit pas vérifier avant mon UPDATE si la ligne existe déjà.

    Auriez vous une idée de comment faire ?

  2. #2
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Bon, je vais garder ma 1ère solution, en insérant dès l'inscription d'un membre une ligne pour chaque forum existant, avec des valeurs 0 par défaut pour le nombre de post, je vois rien d'autre.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    Je désire toujours dans l'application d'un forum pouvoir faire une table qui contiendrait le nombre de messages posté par un membre et ceci pour chaque forum.
    Pourquoi as-tu besoin de créer une telle table ?
    Ne peux-tu pas utiliser une requête SELECT lorsque tu as besoin d'obtenir le nombre de message d'un membre pour un forum ?

    Imaginons que tu ais une table :
    • forum_post (id, membre_id, forum_id, message)


    Tu peux obtenir le nombre de messages postés par un membre M dans un forum F en exécutant la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT count(*)
    FROM forum_post
    WHERE membre_id=M AND forum_id=F
    Pour obtenir le nombre de messages postés par un membre Mdans chque forum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT count(*)
    FROM forum_post
    WHERE membre_id=M
    GROUP BY forum_id

  4. #4
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    C'est à dire que l'affichage sera visualisable dans le profil des membres donc un COUNT se révèle trop lourd au vu du nombre d'affichage qu'il pourrait y avoir des profils utilisateurs.

    Alors qu'une simple incrémentation d'une table réservée à ça(à chaque nouveau post) + un simple sélect pour l'affichage est bien plus léger.

  5. #5
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    http://dev.mysql.com/doc/refman/5.0/...duplicate.html pourrait te dépanner.

    Sinon, un 'count' pour un seul membre (ce n'est pas fait dans un listing des membres) proprement indexé devrait être assez rapide... d'autant plus qu'on ne passe généralement pas son temps à afficher des profils.
    Edit: ha... sauf si on met le nombre de post à gauche des messages comme ici Bien, ouvrir les yeux avant de poster ça peut servir...

  6. #6
    Membre éclairé Avatar de cadoudal56
    Profil pro
    Inscrit en
    Février 2005
    Messages
    694
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 694
    Points : 779
    Points
    779
    Par défaut
    Plutot que de créer une nouvelle table, et si tu n'a pas envie de faire de count, je te conseille d'incrémenter un compteur dans une colonne prévu a cette effet dans ta table utilisateur....

    Ainsi, a chaque fois que l'utilisateur poste.... Hop +1

    Qui plus est, tu récupereras cette info aisement en meme temps que le reste du profil

    @+
    cadou
    PS : Créer une colonne par forum c'est du suicide... Imagine un forum comme celui-ci avec ses 40 à 50 sujets ?

  7. #7
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Citation Envoyé par Sivrît
    http://dev.mysql.com/doc/refman/5.0/...duplicate.html pourrait te dépanner.

    Sinon, un 'count' pour un seul membre (ce n'est pas fait dans un listing des membres) proprement indexé devrait être assez rapide... d'autant plus qu'on ne passe généralement pas son temps à afficher des profils.
    Edit: ha... sauf si on met le nombre de post à gauche des messages comme ici Bien, ouvrir les yeux avant de poster ça peut servir...
    Oui, en effet, des opérations tels que l'affichage du nombre de post, le calcul(pour update) du statut(rang) du posteur seront effectuées et affichés, c'est pour cela que je préfère stocker dans une table réservé à cet usage.

    Citation Envoyé par cadoudal56
    Plutot que de créer une nouvelle table, et si tu n'a pas envie de faire de count, je te conseille d'incrémenter un compteur dans une colonne prévu a cette effet dans ta table utilisateur....

    Ainsi, a chaque fois que l'utilisateur poste.... Hop +1

    Qui plus est, tu récupereras cette info aisement en meme temps que le reste du profil

    @+
    cadou
    PS : Créer une colonne par forum c'est du suicide... Imagine un forum comme celui-ci avec ses 40 à 50 sujets ?
    Oui, c'est bien ce que j'ai l'intention de faire, mais il faut que je le fasse pour chaque forum, si on poste dans le forum X, alors on incrémente le X, etc..

    Et oui, je me rends bien compte que faire une colonne par forum c'est pas gérable, je réfléchi toujours à la meilleure façon de faire ceci.

  8. #8
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Une autre petite question, peut-on mettre un UNIQUE sur 2 colonnes liées ?

    C'est à dire qu'un REPLACE puisse s'effectuer sur la valeur de 2 champs au lieu d'un seul.

  9. #9
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Citation Envoyé par http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
    If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed.
    Donc c'est suivant clefs primaires et indexes, et ces choses là peuvent tout à fait porter sur plusieurs colonnes.

    Et idem
    Citation Envoyé par http://dev.mysql.com/doc/refman/5.0/en/replace.html
    REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 13.2.4, “INSERT Syntax”.
    La première syntaxe me semble plus intéressante car REPLACE fait DELETE puis INSERT en cas d'existance.

  10. #10
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ok, merci, je vais tester ça

  11. #11
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    C'est en effet bien plus optimisé d'utiliser ON DUPLICATE KEY.

    J'ai encore un petit problème qui n'en pas vraiment un, je fais une sélection de la somme des post de tous les forums de chaque membre avec une sous requête :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT membre_id, SUM(nb_post) 
    FROM MEMBRE_POST 
    WHERE membre_id IN( SELECT DISTINCT(createur_id) FROM F_MESSAGE WHERE sujet_id=X) 
    GROUP BY membre_id

    Celle-ci fonctionne très bien, mais je voudrais la transformer en faisant une jointure :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT membre_id, SUM(nb_post) 
    FROM MEMBRE_POST 
    JOIN F_MESSAGE 
    ON membre_id=createur_id 
    WHERE sujet_id=X
    GROUP BY membre_id
    Là ça me renvoi un total multiplié par autant de fois que la condition de jointure est vérifiée.
    J'avais déjà rencontré ce problème,mais je me rappelle plus de la solution

    Comment faire pour obtenir un résultat correct en faisant une jointure ?

    Ma requête en bon français pourrait se résumer à :
    sélection de la somme des post des membres ses membres ont postés dans le sujet x

  12. #12
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Ca c'est un classique... et ce n'est pas forcément évident à résoudre.

    Il faudrait que la jointure fasse du 1-1. Bien souvant la solution est de rajouter une condition (que l'on a oublié) mais ici... A moins de rajouter un booléen pour marquer le premier post de chaque utilisateur dans le thread.

    Sinon utiliser SUM(nb_post)/COUNT(message_id) me semble pas mal.

  13. #13
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ah oui, j'avais pas pensé à diviser par un COUNT, j'ai ajouté en même temps un ROUND, et c'est parfait.

    Bon, après je sais pas si la jointure ne s'avère pas plus lourde que la sous requête en procédant ainsi, puis vu que le EXPLAIN, j'ai toujours du mal à les interprèter, je vais quand même garder la jointure.

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. création d'une table dans une base de donnée accèss
    Par zidenne dans le forum Bases de données
    Réponses: 1
    Dernier message: 25/10/2005, 11h54
  2. Question sur la création d'une table
    Par air dans le forum Oracle
    Réponses: 4
    Dernier message: 23/10/2005, 13h46
  3. Réponses: 4
    Dernier message: 19/10/2005, 12h26
  4. Création d'une table avec foreign key
    Par lepierre dans le forum Langage SQL
    Réponses: 5
    Dernier message: 17/09/2004, 15h20
  5. INTERBASE Création d'une table
    Par Corben dans le forum InterBase
    Réponses: 2
    Dernier message: 19/06/2004, 21h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo