Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3270 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Besoin de conseils pour créer une base mysql

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Besoin de conseils pour créer une base mysql

n°1196729
Mams
Posté le 10-09-2005 à 19:36:16  profilanswer
 

Bonjour à tous.
 
J'ai besoin de quelques conseils concernant la création d'une base de données avec mysql / debian / php / phpmyadmin / apache
C'est surtout au niveau du princique que j'ai besoin d'aide.
Avec apache, j'ai déjà mysql qui fonctionne correctement avec phpmyadmin sur une debian.
 
Voici un exemple de ce que j'aimerai avoir comme base de données :
 
http://mams51.free.fr/photos/base_pain.gif
 
Le but est dans cet exemple de répertorier tous les prix des produits que l'on trouve chez les boulangers. (c'est une idée bizzare mais c'est juste pour avoir un exemple  :D  )
Chaque entrée dans la base correspond à un produit chez un boulanger. Le même produit peux se retrouver plusieur fois chez un même boulanger dans le cas ou il y aurait un changement de prix. A chaque fois j'enregistre la date de la mise à jour du prix.
Je souhaite conserver les anciens prix afin de pouvoir tracer un historique.
 
Le but final de cette base est de pouvoir proposer à un utilisateur de trouver le prix d'une baguette (ou autre) dans sa ville et au meilleur prix.
 
Mon problème est de savoir comment organiser cette base. Je suppose qu'il faut plusieurs tables, des clés étrangères grace à InnoDB.
Vous remarquerez que les villes seront citées plusieur fois, les départements aussi, les enseignes aussi, les types de produits aussi...  faut'il une base pour chacun de ces éléments ?
 
Merci pour vos premiers conseils


---------------
Je me lève de bonne humeur
mood
Publicité
Posté le 10-09-2005 à 19:36:16  profilanswer
 

n°1196852
Arjuna
Aircraft Ident.: F-MBSD
Posté le 11-09-2005 à 02:12:45  profilanswer
 

Typiquement, tu vas avoir trois tables et non une seule !
 
Une table "boulangerie" :
id
enseigne
adresse
ville
département
 
(tu pourrais t'amuser à faire une table supplémentaire pour mettre les villes et les départements à part mais je doute que ce soit très utile)
 
table produit :
id
nom
 
table prix :
id_boulangerie
id_prix
nom_de_la_personne_qui_a_constate_le_prix (tu peux essayer de faire plus long aussi :D)
date
 
tu peux aussi ajouter une 4° table pour sortir la personne ayant constaté le prix dans une table séparée, surtout si des personnes doivent pouvoir indiquer les prix dans la base via un profile

n°1196950
Mams
Posté le 11-09-2005 à 12:18:06  profilanswer
 

Merci, j'y vois un peu plus claire... mais d'autres questions me viennent à l'esprit.
 
 
table "boulangerie"
-id_boulang
-enseigne
-adresse
-ville
-département
 
si je ne fais pas de table spéciale pour les villes, comment je vais pouvoir offrir à l'utilisateur la possibilité de choisir son département et sa ville ?
 
 
 
table "produits"
-id_produit
-nom_produit  
 
utile même si je ne référence que 5 produits maxi ?
 
 
 
table "prix"
-id_prix
-nom_de_la_personne_qui_a_constate_le_prix
-date
-id_boulangerie clé étrangère innodb ?
-id_produit clé étrangère innodb ?
 
Merci de m'apporter quelques précisions   :hello:


Message édité par Mams le 11-09-2005 à 13:18:43

---------------
Je me lève de bonne humeur
n°1196997
Arjuna
Aircraft Ident.: F-MBSD
Posté le 11-09-2005 à 13:26:17  profilanswer
 

Soit un champ libre (ce que je te conseille), soit une liste générée à partir d'un "select distinct ville, departement from boulangerie".
 
Ceci dit, tu auras le même problème avec des tables spécifiques ville et departement.
 
Recherche dans le forum "autocomplete script", j'avais fait un contrôle en JS compatible avec n'importe quel langage serveur permettant de faire une liste déroulante saisissable.

n°1197001
Arjuna
Aircraft Ident.: F-MBSD
Posté le 11-09-2005 à 13:29:10  profilanswer
 

la table produit me semble très importante en effet, afin de ne pas te retrouver avec des lignes "croissant" et "croissants", ou "pain au chocolat" et "chocolatine".
Il faut savoir qu'outre les fautes de frappe, d'une ville à l'autre les mêmes produits des boulangeries ont des noms différents.
 
Le mieu étant avec les baguettes !
 
En côte d'or :
- Flûte : la toute petit baquette très fine
- Petite baguette
- Grosse baguette
 
A paris :
- Flûte : idem
- Baguette = petite baquette
- Pain = grosse baguette
 
Et dans le nord, ce sera encore différent, dans le sud aussi, à l'ouest... etc.

n°1197002
Arjuna
Aircraft Ident.: F-MBSD
Posté le 11-09-2005 à 13:29:24  profilanswer
 

Et oui, les lignes en bleu sont des foreign keys

n°1197437
Mams
Posté le 12-09-2005 à 10:32:05  profilanswer
 

Merci Arjuna pour ton aide précieuse.
Voici les tables que j'ai créées en fonction des tes conseils et des infos que j'ai pu glaner sur quelques sites.
 
table "boulangeries"
-id_boulangerie
-boulangerie (son nom)
-id_enseigne
-adresse
-ville
-departement
-emplacement (pour plus tard - un lien vers Mappy peut-être)
 
table "enseignes"
-id_enseigne
-enseigne
 
table "noms"  (qui collectera le nom et le passe des utilisateurs enregistrants les nouveau prix)
-id_nom
-nom
-passe
 
table "produits"
-id_produit
-produit
 
table "tarifs"
-id_tarif
-tarif
-id_produit
-id_boulangerie
-date
-id_nom
 
Pour info, j'ai laissé tomber les foreign keys puisque j'ai lu dans un article que cela ne servait pas à joindre des données mais juste à aider dans la maintenance.
 
Mon problème maintenant est plus d'ordre technique que d'organisation comme avant.
Je suis parvenu à trouver sur de nombreux sites, comment afficher les infos de 2 tables, notamment avec la commande LEFT JOIN mais je galère pour trouver des infos concernant la jointure de plusieurs tables.
 
Avec mes tables, je dois déjà joindre les boulangeries avec les enseignes et ensuite dans la table tarifs je dois joindre toutes les autres données. Et là, je cale.
Un peu d'aide serait la bienvenue.


---------------
Je me lève de bonne humeur
n°1200847
Mams
Posté le 16-09-2005 à 09:55:48  profilanswer
 

Pour info, la solution semblerait se trouver du coté de "NATURAL JOIN".
Cette commande permet de joindre les tables en utilisant les colonnes portants le même nom.
 
Bon maintenant je vais m'attaquer aux liste déroulantes avec PHP... je sens que je vais galèrer du fait des jointures  :pt1cable:


---------------
Je me lève de bonne humeur
n°1200867
omega2
Posté le 16-09-2005 à 10:18:21  profilanswer
 

Extrait de la page sur les jointure de la doc de mysql :

Citation :

La clause USING (column_list) recense la liste des colonnes qui doivent exister dans les deux tables. Les clauses USING suivantes sont identiques :  
a LEFT JOIN b USING (c1,c2,c3)a
LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3


Message édité par omega2 le 16-09-2005 à 10:18:37
n°1201425
Mams
Posté le 17-09-2005 à 00:09:37  profilanswer
 

Merci pour cette précision, mais maintenant que j'ai réussi à utiliser NATURAL JOIN et que ça fonctionne correctement (il me semble) je n'y touche plus  :D  
 
Bon bah avant d'attaquer les listes déroulantes, je me heurte à un nouveau problème.
 
Voici ma requete :

Code :
  1. $requete = mysql_query("SELECT *
  2. FROM enseignes NATURAL JOIN boulangeries NATURAL JOIN tarifs NATURAL JOIN produits NATURAL JOIN noms
  3. WHERE produits.produit='baguette' AND boulangeries.ville='paris'
  4. ORDER BY tarifs.tarif" );


Le résultat me donne bien la liste des prix dans l'ordre croissant pour les baguettes dans les boulangeries de la ville choisie.
Mais elle me donne tous les prix de chaque mise à jour de prix alors que j'aimerai n'avoir que le prix de la date de mise à jour la plus récente !
 
j'ai tenté  :

Code :
  1. ORDER BY tarifs.date DESC LIMIT 1 ORDER BY tarifs.tarif


mais évidement cela ne fonctionne pas puisque ORDER BY ne peux être utilisé 2 fois.
 
j'ai alors testé un truc du style :
 

Code :
  1. ORDER BY  tarifs.date DESC LIMIT 1, tarifs.tarif


Pas mieux !
Vous avez une idée ?
A savoir que j'ai aussi regardé MAX mais sans trouver de formule adéquate.
Merci d'avance pour votre aide !


---------------
Je me lève de bonne humeur
mood
Publicité
Posté le 17-09-2005 à 00:09:37  profilanswer
 

n°1201991
Mams
Posté le 18-09-2005 à 23:13:22  profilanswer
 

Je n'avance plus...  :??:  
 
un peu d'aide s'il vous plait !


---------------
Je me lève de bonne humeur
n°1202751
Arjuna
Aircraft Ident.: F-MBSD
Posté le 19-09-2005 à 19:46:30  profilanswer
 

Quelle version de MySQL ?
 
Sinon, perso, je déteste la notation avec le mot-clé "JOIN" pour faire des jointures. Certains SGBD ne la supportent d'ailleurs pas (les anciennes versions d'Oracle par exemple) et je trouve ça très bien :)
 
Donc ta requête, je ne la ferais pas comme ça mais :
(d'autant plus que le NATURAL JOIN est à éviter, car il se base sur le Foreign Keys : s'il y a deux FK pointant sur la même table, il ne sait pas laquelle prendre et ça peut faire n'importe quoi !)

Code :
  1. SELECT *
  2. FROM noms, enseignes, boulangeries, tarifs, produits
  3. WHERE produits.produit='baguette'
  4. AND tarifs.id_produit = produits.id_produit
  5. AND boulangeries.id_boulangerie = tarifs.id_boulangerie
  6. AND boulangeries.ville='paris'
  7. AND enseignes.id_enseigne = boulangerie.id_enseigne
  8. AND noms.id_nom = tarifs.id_nom
  9. ORDER BY tarifs.tarif


 
Bon, ça, c'est le début.
 
Ensuite, si tu as une version récente de MySQL ( >= 4.1 il me semble) alors tu peux faire :
 
 

Code :
  1. SELECT *
  2. FROM noms n, enseignes e, boulangeries b, tarifs t, produits p
  3. WHERE p.produit='baguette'
  4. AND t.id_produit = p.id_produit
  5. AND t.id_tarifs =
  6. (
  7.    select max(t2.id_tarifs)
  8.    from tarifs t2
  9.    where t2.id_produit = t.id_produit
  10.    and t2.id_boulangerie = t.id_boulangerie
  11.    and t2.id_nom = t.id_nom
  12.    and t2.date =
  13.    (
  14.       select max(t3.date)
  15.       from tarifs t3
  16.       where t3.id_boulangerie = t2.id_boulangerie
  17.       and t3.id_produit = t2.id_produit
  18.       and t3.id_nom = t2.id_nom
  19.    )
  20. )
  21. AND b.id_boulangerie = t.id_boulangerie
  22. AND b.ville='paris'
  23. AND e.id_enseigne = b.id_enseigne
  24. AND n.id_nom = t.id_nom
  25. ORDER BY t.tarif


 
Voilà :)
 
Ca, c'est pour le cas où tu stockes la date uniquement au format "date" et non "datetime" (c'est à dire avec seulement le jour, pas les heures)
 
Explication :
-> Tu fais ta requête initiale
-> Tu la filtre en ne prenant que les tarifs sasis pour chaque triplet (id_boulangerie, id_produit, id_nom) de la ligne en cours, pour lesquels la date de mise à jour est la plus récente. Et vu que si tu ne stockes pas l'heure, tu peux avoir des doublons, tu refiltres sur l'id_tarif le plus grand (donc logiquement le plus récent) afin d'avoir réellement la dernière ligne mise à jour.


Message édité par Arjuna le 19-09-2005 à 19:48:07
n°1203241
Mams
Posté le 20-09-2005 à 13:18:08  profilanswer
 

Merci pour ton aide précieuse Arjuna.
Je viens de mettre à jour ma version de Mysql. J'étais en 3.23  :pfff:  Maintenant je suis en 4.1.11
Mon format de date est "datetime" et je n'utilise pas de "foreign keys".
 
Mon but est d'afficher les prix d'un produit dans l'ordre croissant pour chaque boulangerie d'une ville et uniquement avec la dernière mise à jour.
Ce qui permettra à un utilisateur de trouver le meilleur prix pour sa baguette de pain dans sa ville.
 
En suivant tes explications, j'ai pondu ce code :
 

Code :
  1. $requete = mysql_query("SELECT *
  2. FROM enseignes e, boulangeries b, tarifs t, produits p, noms n
  3. WHERE t.date =
  4. (
  5.  SELECT MAX(t2.date)
  6.  FROM tarifs t2
  7.  WHERE t2.id_nom = t.id_nom
  8.  AND t2.id_produit = t.id_produit
  9.  AND t2.tarif = t.tarif
  10.  AND t2.id_boulangerie =
  11.  (
  12.   SELECT DISTINCT(t3.id_boulangerie)
  13.   FROM tarifs t3
  14.   WHERE t3.id_produit = t2.id_produit
  15.   AND t3.id_nom = t2.id_nom
  16.  )
  17. )
  18. AND b.id_enseigne = e.id_enseigne
  19. AND t.id_nom = n.id_nom
  20. AND t.id_boulangerie = b.id_boulangerie
  21. AND t.id_produit = p.id_produit
  22. ORDER BY t.tarif" );


 
Mais cela ne fonctionne pas  :(  J'ai une erreur lors du "fetch_array"  Je me suis planté où ?


---------------
Je me lève de bonne humeur
n°1203354
Arjuna
Aircraft Ident.: F-MBSD
Posté le 20-09-2005 à 14:20:48  profilanswer
 

je regarderai ce soir, là je suis au boulot et j'ai pas le temps :)
 
mais je pense à toi ;)

n°1203583
Mams
Posté le 20-09-2005 à 16:34:09  profilanswer
 

Cool, merci  :jap:


---------------
Je me lève de bonne humeur
n°1203609
Berceker U​nited
PSN : berceker_united
Posté le 20-09-2005 à 16:58:48  profilanswer
 

si tu es sous php utilise la fonction mysql_error() pour voir l'erreur généré

n°1203651
Mams
Posté le 20-09-2005 à 17:29:47  profilanswer
 

Merci pour l'info, c'est vrai que ça peut aider  :)  
Voici ce que j'ai ajouter juste après "ORDER BY t.tarif" );"

Code :
  1. echo mysql_errno($connexion)." __ ".mysql_error($connexion);


Et voici le résultat : 1242 __ Subquery returns more then 1 row


---------------
Je me lève de bonne humeur
n°1203673
Berceker U​nited
PSN : berceker_united
Posté le 20-09-2005 à 17:53:42  profilanswer
 

La sous requete renvoy plus d'un résultat. Cela ne peut pas fonctionner.

n°1203684
omega2
Posté le 20-09-2005 à 17:57:10  profilanswer
 

utiliser un = si la sous requette retourne 1 seule valeur
utiliser "in" si ca en retourne plusieurs.


Message édité par omega2 le 20-09-2005 à 17:57:26
n°1203827
Arjuna
Aircraft Ident.: F-MBSD
Posté le 20-09-2005 à 19:55:48  profilanswer
 

Je crois que t'as rien panné à ma requête :o
 
Copie simplement ma requête et regarde ce qu'elle te retourne. Normalement, elle est bonne, j'ai beau chercher, je ne vois pas en quoi elle ne répond pas à ton problème :p (et gère les insertions par lot, genre 2 personnes qui saisissent un prix pour un même produit, une même boulangerie, et au même instant T au quart de pouillème de microseconde près - cas typique lors d'une intégration de fichier notamment)

n°1203829
Arjuna
Aircraft Ident.: F-MBSD
Posté le 20-09-2005 à 19:56:40  profilanswer
 

En fait t'as juste à virer mes clauses sur produit et ville, qui ne retournent que les baquettes à paris.

n°1203831
Arjuna
Aircraft Ident.: F-MBSD
Posté le 20-09-2005 à 19:57:25  profilanswer
 

quoique non, t'as pas à les virer, puisque c'est par ce couple que tu veux faire tes filtres

n°1203835
omega2
Posté le 20-09-2005 à 20:01:18  profilanswer
 

Citation :

AND t2.id_boulangerie =  
        (  
            SELECT DISTINCT(t3.id_boulangerie)  
            FROM tarifs t3  
            WHERE t3.id_produit = t2.id_produit  
            AND t3.id_nom = t2.id_nom

        )

Je ne vois rien dans cette partie qui limite le résultat à une seule ligne. [:atlantis]
Donc ne pas mettre un = devant ce select.  

n°1203890
Arjuna
Aircraft Ident.: F-MBSD
Posté le 20-09-2005 à 22:41:39  profilanswer
 

surtout, la requête ne retournera de toute façon pas ce qu'il veut.
 
j'me tue à vous le dire :o
 
faut utiliser la mienne :p

n°1203892
omega2
Posté le 20-09-2005 à 22:55:11  profilanswer
 

Arjuna > Par expérience, j'ai pas besoin de lire sa requette pour savoir que dés qu'il aura sufisament de données, il aura plus qu'a lancer sa requette et se coucher par ce qu'il aura pas le résultat avant le lendemain.
En plus vu son erreur dans la requette, je suis pas aller jusqu'a regarder si sa requette risquait de lui retourner le bon résultat. ;)

Message cité 1 fois
Message édité par omega2 le 20-09-2005 à 22:56:38
n°1203897
Mams
Posté le 20-09-2005 à 23:12:00  profilanswer
 

Arjuna a écrit :

Je crois que t'as rien panné à ma requête :o

Hi hi, je croyais avoir compris mais vu que je débute, je plane totalement !

omega2 a écrit :

Je ne vois rien dans cette partie qui limite le résultat à une seule ligne. [:atlantis]
Donc ne pas mettre un = devant ce select.

J'ai remplacé "=" par "IN" pour la 2ième sous requete et ça m'a sorti toutes les entrées de la tables tarifs  :??:  
-
-
-
-
-
-
-Plus tard pendant l'écriture de ce message j'ai relu tes explications Arjuna

Arjuna a écrit :

-> Tu la filtre en ne prenant que les tarifs sasis pour chaque triplet (id_boulangerie, id_produit, id_nom) de la ligne en cours, pour lesquels la date de mise à jour est la plus récente

-
-
-
-
-Et je pense avoir compris

Code :
  1. $requete = mysql_query("SELECT *
  2. FROM enseignes e, boulangeries b, tarifs t, produits p, noms n
  3. WHERE t.date =
  4. (
  5.  SELECT MAX(t2.date)
  6.  FROM tarifs t2
  7.  WHERE t2.id_produit = t.id_produit
  8.  AND t2.id_boulangerie = t.id_boulangerie
  9. )
  10. AND b.id_enseigne = e.id_enseigne
  11. AND t.id_nom = n.id_nom
  12. AND t.id_boulangerie = b.id_boulangerie
  13. AND t.id_produit = p.id_produit
  14. AND p.produit = 'baguette'
  15. ORDER BY t.tarif" );

Il me semble que ça fonctionne correctement. Mais il va falloir que je remplisse un peu mes tables pour êtres 100% sur que ce soit Ok.
Un grand merci pour votre aide et plus particulièrement à Arjuna.  :jap:  
 
Je m'attaque donc maintenant aux listes déroulantes PHP. Ne partez pas trop loin, je risque d'avoir besoin de vous d'ici peu de temps  :D  
 
Tchao  :hello:


---------------
Je me lève de bonne humeur
n°1205048
Arjuna
Aircraft Ident.: F-MBSD
Posté le 22-09-2005 à 13:57:40  profilanswer
 

omega2 a écrit :

Arjuna > Par expérience, j'ai pas besoin de lire sa requette pour savoir que dés qu'il aura sufisament de données, il aura plus qu'a lancer sa requette et se coucher par ce qu'il aura pas le résultat avant le lendemain.
En plus vu son erreur dans la requette, je suis pas aller jusqu'a regarder si sa requette risquait de lui retourner le bon résultat. ;)


Par expérience (bon, avec Oracle et SQL Server, certes), ce type de requête est très rapide normalement.

n°1205050
Arjuna
Aircraft Ident.: F-MBSD
Posté le 22-09-2005 à 13:59:22  profilanswer
 

Le problème des sous-requêtes, c'est quand elle rammènent plusieurs lignes (ici ce n'est pas le cas) et filtrent sur des données différentes de la requête principale (ce n'est toujours pas le cas ici).

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Besoin de conseils pour créer une base mysql

 

Sujets relatifs
Moteur Physique 2D ( 2D Physical Engine) – Besoin d’informationscréer un fichier .txt et faire un lien sur la .jsp / href (Websphere)
[Perl] Mon script a besoin de privileges supplémentairesPublipostage Word avec PHP/MySql
Demande de conseils pour mon site webinfo bdd Mysql
[Au secour]>>Comment créé t-on une base de donnée svp ??créer une IHM pour mon programme en Fortran
[MySQL] un GRANT sur toutes les bases mais sur une table donnée?Base access impossible à ouvrir "MSysDb" non trouvé...access 2003
Plus de sujets relatifs à : Besoin de conseils pour créer une base mysql


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR