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

PHP & Base de données Discussion :

Structure DB et récupération de données [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Structure DB et récupération de données
    Bonjour à tous,
    alors voilà je vous expose mon problème, je suis actuellement en train en train d'écrire un petit script qui est sensé récupérer des données dans un array pour les afficher sous forme de tableau et je suis face à 1 gros problème qui a parasité toute mon attention depuis avant-hier soir et qui concerne la structure de la base de donnée qui se présente comme cela actuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE `membre` (
    `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `type` ENUM( '0', '1' ) NOT NULL ,
    `titre` VARCHAR( 255 ) NOT NULL ,
    `nom` VARCHAR( 255 ) NOT NULL ,
    `prenom` VARCHAR( 255 ) NOT NULL
    ) ENGINE = InnoDB;
    sachant que selon le type d'information qui est inséré dans la base certains champs seront vides, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    INSERT INTO `membre` (
    `id` ,
    `type` ,
    `titre` ,
    `nom` ,
    `prenom`
    )
    VALUES (
    NULL , '0', '', 'David', 'Dupont'
    ), (
    NULL , '1', 'Seigneur', 'François', 'Damien'
    );
    On aura le membre Dupont de type 0 avec aucun titre assigné tandis que l'utilisateur Damien de type 1 aura un titre assigné.

    Je veux récupérer toutes les informations contenues dans la base de donnée et les afficher ensuite dans un tableau de ce genre :

    -------------------------------------------------------------------------
    + Membres (Titre et si Titre vide alors Nom Prénom) | + Contact
    -------------------------------------------------------------------------
    Seigneur | 4
    -------------------------------------------------------------------------
    David Dupont | 3
    -------------------------------------------------------------------------
    Le problème c'est que j'utilise cette requête SQL pour récupérer les informations et les trier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "SELECT * FROM membre ORDER BY titre, nom"
    et là c'est le drame comme certains champs titres sont vides ils apparaissent en premier sur ma liste alors que je veux qu'ils soient triés par ordre alphabétique décroissant en prenant en compte le champ nom si le champ titre est vide.

    Je m'interroge donc s'il ne serait pas mieux de séparer cette table en 2 en créant par exemple une table membre qui enregistrerais tous les membres de type 0 (qui n'ont pas de titre) et une table membre_sup qui enregistrerais tous les membres de type 1 (qui ont un titre) sachant que ma table membre est reliée par le champ id à une table contact qui stocke des contacts et qui prend cette forme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE `contact` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `membre_id` INT UNSIGNED NOT NULL ,
    `pseudo` VARCHAR( 255 ) NOT NULL ,
    `mail` VARCHAR( 255 ) NOT NULL ,
    `favori` ENUM( '0', '1' ) NOT NULL ,
    INDEX ( `membre_id` )
    ) ENGINE = InnoDB;
    auriez vous s'il vous plaît une solution ou une indication qui pourrait m'aider à résoudre ce problème sachant que je suis maniaque quant à l'optimisation de mes scripts et que j'affiche ces données en me servant d'un système de template que j'ai écris moi même et qui se fait par une boucle faisant appel à un preg_replace() structuré ainsi : $template = preg_replace( '/{'.$tag.'}/', $array, $template); ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <table>
    <tr>
      <th>membre</th>
      <th>contact</th>
    </tr>
    <!--START -->
    <tr>
      <td>{membre.disp}</td>
      <td>{membre.contact}</td>
    </tr>
    <!-- END -->
    </table>

  2. #2
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Je m'interroge donc s'il ne serait pas mieux de séparer cette table en 2
    A mon avis oui.

    Si on fait ça de manière assez scolaire, donc stricte, et bien on s'aperçoit que la donnée "titre" est dépendante de "type".
    Au bout, il peut avoir des incohérences entre ces 2 données, comme avoir un contenu au niveau du titre alors que la valeur de "type" est 0 (qui signifie "Pas de titre").
    Rien que ça signifie que les données "type" et "titre" ne devraient être dans une même table, mais à part.
    Enfin, si on est stricte.

    Mais encore, (apparemment), dans le cas où le "type" est 0 (pas de titre), faudrait exploiter le "nom/prenom" à la place.

    Au feeling comme ça, je verrais quelque chose comme :
    membre
    id | nom | prenom
    1 | n1 | p1
    2 | n2 | p2
    3 | n3 | p3
    4 | n4 | p4
    membre_type
    id | type | titre
    1 | 1 | | titre1
    3 | 1 | |titre3
    Ici, seul les membres 1 et 3 on des titres.
    Par contre, j'ai quand même mis le "type" dans cette table "membre_type", mais ça dépend de ce que représente un type.
    Si un "type" est une personne ayant un "titre" (ce qui a l'air d'être le cas), alors le champ "type" est inutile. Le simple fait d'être présent dans cette table signifie que le membre a un type 1.
    Si à l'avenir il peut avoir plusieurs autres types (0, 1, 3, etc ...) alors il est peut être nécessaire.

    Coté SQL, il faudra faire une jointure sur les 2 tables.
    Puis avec une condition au niveau du champ on peu faire les remplacement.
    Exemple :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT id,
    if (mt.id, mt.titre, CONCAT(m.nom, " ", m.prenom)) AS nom_ou_titre
    FROM membre m
    LEFT JOIN membre_type mt ON m.id = mt.id
    ORDER BY nom_ou_titre

  3. #3
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    et là c'est le drame comme certains champs titres sont vides ils apparaissent en premier sur ma liste alors que je veux qu'ils soient triés par ordre alphabétique décroissant en prenant en compte le champ nom si le champ titre est vide.
    Soit tu mets le champ titres à NOT NULL soit tu truande la requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT * FROM membre WHERE titre != "" ORDER BY titre, nom
    UNION
    SELECT * FROM membre WHERE titre = "" ORDER BY nom
    Ou alors tu fais une relation 1-n comme te l'as expliqué RunCodePHP ci dessus. C'est encore la meilleure solution (surtout si plusieurs membres partagent leur titre).

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Hmmm je suis tellement concentré sur ce problème que même en essayant d'être clair j'arrive à ne pas l'être

    Je vais bien exposer les relations entre les bdd et le but du script

    voilà en faite je dois gérer l'insertion, l'édition, la suppression et l'affichage d'une base de donnée qui contient une liste de membres, je m'explique:

    actuellement j'ai une seule table membre qui contient tous les membres enregistrés sachant qu'il n'y a que 2 types de membres:
    les membres "standard" et les membres "premium" défini par le champ type, dans cette table qui incrémente automatiquement un id à chaque nouvelle entrée je stock les infos des membres à savoir leur nom, prénom, mail et je possède aussi un champ titre différent pour chaque membre car c'est le membre qui se l'attribue (c'est un nom de guilde mais il peut y en avoir 2 similaires dans la bdd car les membres possèdent aussi un champ serveur mais ça je peux le gérer, le soucis n'est pas vraiment là) voilà pour la structure actuelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    membre :
     
    id, int
    serveur, int
    type, enum( "0", "1")
    titre, varchar(255)
    nom, varchar(255)
    prenom, varchar(255)
    mail, varchar(255)
    ce que j'envisageais de faire c'était donc de scinder la table de cette manière:

    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
    membre:
    id, int Auto incrementé
    type, enum ("0", "1") // défini si on va opérer sur la table premium ou standard
    serveur, int (lié à une table serveur)
     
    premium:
    id, int AI
    id_membre, int UNIQUE // si 1 est dans premium il ne peut pas être dans standard
    titre, varchar(255)
     
    standard:
    id, int AI
    id_membre, int UNIQUE // si 1 est dans standard il ne peut pas être dans premium
     
    et enfin une table contact telle que:
    id, int AI
    id_membre, int // il peut y avoir plusieurs contacts pour un même membre
    nom, varchar
    prenom, varchar
    mail, varchar
    favori, enum( "0", "1") // on défini si c'est le contact principal (chef de guilde)
    est ce optimum si on part de l'hypothèse que des milliers de personnes vont peut être lire et écrire sur cette table simultanément à partir de mon script php? et surtout comment présenter ma requête pour afficher mes donnée dans mon tableau?
    Voilà merci d'avance.

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Ce que je te proposais c'est quasi la même chose de ce que tu as fais.
    Faut juste supprimer le champ "type", car tu confirme maintenant qu'il y aurait que 2 types.
    Et puis renommer "membre_type" en "premium" et on a la même chose.

    Sauf que la table "premium" ne devrait pas avoir d'ID auto_incremente, juste l'Id des membres.
    Mettre juste comme clé primaire "id" et comme valeurs les IDs de membre.
    Il ne pourra pas avoir 2 fois le même membre.

    Et la table "standard" est inutile car elle ne contient rien d'autre que les mêmes IDs que la table "membre". (de même qu'il ne doit pas avoir 2 fois le même membre).


    Faut juste percevoir que le seul fait qu'un membre soit présent dans la table "premium", c'est justement un premium, et que sa non-présence c'est qu'il sera alors "standard".
    Présent (1) -> Premium
    Pas présent (0) -> Standard.

    La notion de "type" se fait quasi naturellement, cette information (0 ou 1) est inutile, elle fait même doublon et du coup être contradictoire avec les enregistrements dans "premium".

    En somme, imagine que tu mettes comme type 1 et que l'id correspondant ne se trouve pas dans la table "premium", c'est contradictoire, c'est un risque de bug au niveau du code (php).
    Même chose inversement : type 0 alors que l'id est présent.


    Puis les noms, prénom seraient mieux dans la table "membre" comme tu l'as fais au départ au lieu de "contact", car ça me semble plus naturel.

    Pour la table "contact", je ne sais pas trop ce quelle représente.
    Si c'est une liste de contact des membres ou si c'est une table qui offre la possibilité qu'un membre ait plusieurs adresses mails.
    Faut voir.


    Enfin, tout ça bien sûr si j'ai bien compris.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Hmmm effectivement la table standard peut sauter tout comme le champ id auto incrémenté de la table premium, c'est bien vu et ça confirme aussi que je dois vraiment être à la limite du burnout avec ce problème de structure

    Pour ce qui est de la table contact en faite elle va contenir le nom, prénom, mail, tel etc etc de toutes les personnes à contacter qui soient en relation avec un membre 'xx' (où xx représente l'id du membre).

    Exemple:
    je suis un membre (peu importe que je sois premium ou non)
    je possède une fiche spécifique
    j'ai 3 contacts:
    - contact 1, riri, mail@riri.tld
    - contact 2, fifi, mail@fifi.tld
    - contact 3, loulou, mail@loulou.tld

    Lorsque j'affiche tous les membres la table contact n'est pas parcourue,
    mais lorsque j'affiche une fiche de membre la table membre est lue et la table contact reliée par l'id membre est lue aussi avant d'être affichée.
    J'espère que c'est plus limpide comme ça, parce que j'ai énormément de mal à l'être aujourd'hui

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Pour ce qui est de la table contact en faite elle va contenir le nom, prénom, mail, tel etc etc de toutes les personnes à contacter qui soient en relation avec un membre 'xx'
    Si ce sont les mails, pseudo, tel, etc ... des membres, je ne vois pas l'utilité de créer une autre table pour ça.

    A part offrir la possibilité qu'un membres ait plusieurs adresses mails ou plusieurs n° tel, etc ... là ça demandera de créer des tables supplémentaires pour représenter ça.

    Sinon, si un membre à : 1 pseudo, 1 mail, 1 tel, etc ... alors il y a une relation 1-1, donc ces données devraient fusionnées/basculées dans la table "membres".

    Si c'est une question d'optimisation de vouloir les séparer, faudrait vraiment faire un test si 4 ou 5 champs supplémentaires provoquent un ralentissement des requêtes.
    4 ou 5 champs ça me semble peu, pas sûr que ça vaille le coup.
    Faut voir.

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Effectivement la structure relationnelle convient parfaitement à ce que je veux obtenir (à tête reposée ça semble bien optimisé pour tenir une forte charge)

    et j'ai donc adopté une structure à 2 tables:

    membres et premium

    pour ce qui est de la table contact en faite elle associe à chaque membre un ou plusieurs contacts (id, id_membre, nom, prenom, mail) qui ne proviennent pas de la table membre et dont j'ai absolument besoin ^^

    Maintenant le problème qui se pose c'est lorsque je récupère les informations de la table avec ma requête sql, je m'explique je suis toujours face au même problème que précédemment :

    admettons que ma table membre soit peuplée de cette manière:

    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
     
    membre:
    id | nom
    1  | a
    2  | y
    3  | b
    4  | e
    5  | g
    6  | r
    7  | y
    8  | z
    9  | a
     
    premium
    id | titre
    1  | riri
    7  | fifi
    8  | loulou
    comment construire ma requête pour que mon tableau de membres s'affiche de cette manière (triés par leur nom d'affichage, c'est à dire par le champ nom avec s'il est membre premium simultanément le champ titre)?

    tableau de 2 colonnes par exemple tel que : id - nom d'affichage
    9 - a
    3 - b
    4 - e
    7 - fifi
    5 - g
    8 - loulou
    6 - r
    1 - riri
    2 - y

  9. #9
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    SELECT id,
    IF (p.id, p.titre, CONCAT(m.nom, " ", m.prenom)) AS nom_ou_titre
    FROM membre m
    LEFT JOIN premium p ON m.id = p.id
    ORDER BY nom_ou_titre
    As tu essayé ce que j'avais mis au début (car théoriquement ça devrait le faire) ?

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    enfin ça fonctionne !!!! U_U

    Un énorme merci, ça m'a pris le chou pendant un long moment cette table horrible

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

Discussions similaires

  1. Récupération de données structurées dans un fichier
    Par magicland dans le forum Débuter
    Réponses: 6
    Dernier message: 08/06/2008, 15h55
  2. Réponses: 2
    Dernier message: 28/07/2005, 10h15
  3. [ DB2] => [ORACLE] Récupération de données
    Par LeDid dans le forum DB2
    Réponses: 3
    Dernier message: 25/06/2003, 17h10
  4. Réponses: 13
    Dernier message: 20/03/2003, 08h11
  5. [XMLRAD] récupération de donnée
    Par Mitch79 dans le forum XMLRAD
    Réponses: 7
    Dernier message: 30/01/2003, 15h36

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