Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD > PHP & MySQL
PHP & MySQL Forum d'entraide sur les fonctions MySQL avec PHP. Avant de poster -> FAQ MySQL, Cours MySQL et Sources MySQL. Pour les questions concernant le moteur MySQL plutôt que les fonctions PHP, merci d'utiliser le forum MySQL.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/03/2011, 12h38   #1
Invité de passage
 
Inscription : mars 2011
Messages : 6
Détails du profil
Informations forums :
Inscription : mars 2011
Messages : 6
Points : 1
Points : 1
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 :
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 :
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 :

Citation:
-------------------------------------------------------------------------
+ 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 :
"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 :
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 :
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>
menthe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h08   #2
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 707
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 707
Points : 3 277
Points : 3 277
Salut

Citation:
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
Citation:
id | nom | prenom
1 | n1 | p1
2 | n2 | p2
3 | n3 | p3
4 | n4 | p4
membre_type
Citation:
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 :
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
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h15   #3
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

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

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
Citation:
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 :
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).
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 15h14   #4
Invité de passage
 
Inscription : mars 2011
Messages : 6
Détails du profil
Informations forums :
Inscription : mars 2011
Messages : 6
Points : 1
Points : 1
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 :
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 :
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.
menthe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 16h10   #5
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 707
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 707
Points : 3 277
Points : 3 277
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.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 17h05   #6
Invité de passage
 
Inscription : mars 2011
Messages : 6
Détails du profil
Informations forums :
Inscription : mars 2011
Messages : 6
Points : 1
Points : 1
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).

Citation:
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
menthe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 20h08   #7
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 707
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 707
Points : 3 277
Points : 3 277
Citation:
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.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h04   #8
Invité de passage
 
Inscription : mars 2011
Messages : 6
Détails du profil
Informations forums :
Inscription : mars 2011
Messages : 6
Points : 1
Points : 1
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 :
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)?

Citation:
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
menthe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h14   #9
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 707
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 707
Points : 3 277
Points : 3 277
Citation:
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) ?
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/03/2011, 21h29   #10
Invité de passage
 
Inscription : mars 2011
Messages : 6
Détails du profil
Informations forums :
Inscription : mars 2011
Messages : 6
Points : 1
Points : 1
enfin ça fonctionne !!!! U_U

Un énorme merci, ça m'a pris le chou pendant un long moment cette table horrible
menthe est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h51.


 
 
 
 
Partenaires

Hébergement Web