Besoin de conseils pour créer une base mysql - SQL/NoSQL - Programmation
Marsh Posté le 11-09-2005 à 02:12:45
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 )
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
Marsh Posté le 11-09-2005 à 12:18:06
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
Marsh Posté le 11-09-2005 à 13:26:17
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.
Marsh Posté le 11-09-2005 à 13:29:10
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.
Marsh Posté le 12-09-2005 à 10:32:05
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.
Marsh Posté le 16-09-2005 à 09:55:48
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
Marsh Posté le 16-09-2005 à 10:18:21
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 : |
Marsh Posté le 17-09-2005 à 00:09:37
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
Bon bah avant d'attaquer les listes déroulantes, je me heurte à un nouveau problème.
Voici ma requete :
Code :
|
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 :
|
mais évidement cela ne fonctionne pas puisque ORDER BY ne peux être utilisé 2 fois.
j'ai alors testé un truc du style :
Code :
|
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 !
Marsh Posté le 18-09-2005 à 23:13:22
ReplyMarsh Posté le 19-09-2005 à 19:46:30
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 :
|
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 :
|
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.
Marsh Posté le 20-09-2005 à 13:18:08
Merci pour ton aide précieuse Arjuna.
Je viens de mettre à jour ma version de Mysql. J'étais en 3.23 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 :
|
Mais cela ne fonctionne pas J'ai une erreur lors du "fetch_array" Je me suis planté où ?
Marsh Posté le 20-09-2005 à 14:20:48
je regarderai ce soir, là je suis au boulot et j'ai pas le temps
mais je pense à toi
Marsh Posté le 20-09-2005 à 16:58:48
si tu es sous php utilise la fonction mysql_error() pour voir l'erreur généré
Marsh Posté le 20-09-2005 à 17:29:47
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 :
|
Et voici le résultat : 1242 __ Subquery returns more then 1 row
Marsh Posté le 20-09-2005 à 17:53:42
La sous requete renvoy plus d'un résultat. Cela ne peut pas fonctionner.
Marsh Posté le 20-09-2005 à 17:57:10
utiliser un = si la sous requette retourne 1 seule valeur
utiliser "in" si ca en retourne plusieurs.
Marsh Posté le 20-09-2005 à 19:55:48
Je crois que t'as rien panné à ma requête
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 (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)
Marsh Posté le 20-09-2005 à 19:56:40
En fait t'as juste à virer mes clauses sur produit et ville, qui ne retournent que les baquettes à paris.
Marsh Posté le 20-09-2005 à 19:57:25
quoique non, t'as pas à les virer, puisque c'est par ce couple que tu veux faire tes filtres
Marsh Posté le 20-09-2005 à 20:01:18
Citation : AND t2.id_boulangerie = |
Je ne vois rien dans cette partie qui limite le résultat à une seule ligne.
Donc ne pas mettre un = devant ce select.
Marsh Posté le 20-09-2005 à 22:41:39
surtout, la requête ne retournera de toute façon pas ce qu'il veut.
j'me tue à vous le dire
faut utiliser la mienne
Marsh Posté le 20-09-2005 à 22:55:11
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.
Marsh Posté le 20-09-2005 à 23:12:00
Arjuna a écrit : Je crois que t'as rien panné à ma requête |
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. |
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 :
|
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.
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
Tchao
Marsh Posté le 22-09-2005 à 13:57:40
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. |
Par expérience (bon, avec Oracle et SQL Server, certes), ce type de requête est très rapide normalement.
Marsh Posté le 22-09-2005 à 13:59:22
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).
Marsh Posté le 10-09-2005 à 19:36:16
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 :
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 )
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