sélectionner les options existantes d'articles

Petit nouveau ! | 8 Messages

16 févr. 2010, 13:04

Bonjour à tous,

j'ai un problème de sélection d'éléments dans une base de données. J'ai recherché dans le forum mais je n'ai pas trop de réponse adaptée à mon cas.

situation de départ:

table 1 : Catalogue. Champs : id, titre, cat_option (et autres mais pas nécessaire pour expliquer mon problème). le champs cat_option est la clé étrangère de la table Options
table 2 : Options. Champs : id`, `titre

Dans la table catalogue, dans le champs cat_option, je stocke les valeurs des options qu'a un article du catalogue séparées par des virgules. EX : 1,4,6,2

Sur le front-end, j'ai fait une page pour faire une recherche d'articles basée sur les options.

j'affiche donc toutes les options, on coche les options désirées et en faisant "rechercher", on affiche tous les articles qui ont les options cochées.


Ma question :

est-il possible d'afficher dans la page de recherche (celle où on coche les options désirées) seulement les options qui sont déjà attribuées à un article ? Et donc ne pas avoir des options inutilisées pour l'instant.

Quelle serait la sélection à faire en sql?

merci de votre aide, j'espère avoir été assez clair :)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

17 févr. 2010, 12:40

Bonjour,

déjà cela saute aux yeux : problème de modélisation.

Pour 1 catalogue il y a 0 ou n option, donc il faut une relation entre les deux.

Catalogue(id_catalogue)
possede(fk_id_catalogue, fk_id_option) ==> relation
Options(id_option)

Pour ton exemple (avec le catalogue numéro 1) tu aurais donc dans "possede" :
fk_id_catalogue | fk_id_option
1 | 1
1 | 4
1 | 6
1 | 2

Ta modélisation actuelle serait valable si à 1 catalogue correspondait 1 et 1 seule option.

Dis toi que si tu stockes plusieurs valeurs dans une même colonne, avec un séparateur pour les différencier, c'est généralement qu'il y a un problème.

Autant travailler sur un truc propre, je t'invite à modifier ton modèle avant de travailler sur ton soucis.

Des ressources pour te renseigner sur la modélisation de base de données :
faq-tutoriels/les-jointures-niveau-debutant-t21507.html
http://www.commentcamarche.net/contents/merise/mcd.php3

Ou une recherche sur le we avec "merise", "modélisation" etc :)

Petit nouveau ! | 8 Messages

18 févr. 2010, 10:43

merci de ton message.

aie... le problème c'est que j'ai déjà commencé à remplir la base :roll:

bon, je vais essayer de réparer ça.

mais comment tu fais pour que dans la table catalogue cela rajoute un champs à chaque fois que tu ajoutes une option à un article ?

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

18 févr. 2010, 13:06

J'avais loupé les articles, du coup je comprends encore moins. Si les options sont appliquées aux articles, pourquoi les stocker dans le catalogue ?! :shock:

ça paraît plutôt standard ce que tu fais :
Un catalogue contient 1 ou plusieurs articles
Un article appartient à 1 ou plusieurs catalogues (oui ?)
=> table de relation entre "catalogue" et "articles"

Un article peut avoir 1 ou plusieurs options
Une option peut appartenir à 1 ou plusieurs articles
=> table de relation entre "articles" et "options"

Pour remplir les relations, soit tu le gères dans ton code, soit tu utilises un ORM qui le fera pour toi. Mais avant d'utiliser un ORM je pense qu'il faudrait maîtriser les concepts de modélisation de base.

Si ta base est remplie ce n'est pas si grave, tu peux faire un petit script qui pour chaque catalogue va extraire les options saisies, et faire les INSERT correspondant. Mais je répère, je ne comprends pas pourquoi les options sont stockées dans le catalogue.

Petit nouveau ! | 8 Messages

18 févr. 2010, 15:07

non il n'y a pas de table articles, excuse-moi je n'ai pas été clair !

dans la table catalogue, les articles sont directement saisis, car il n'y a qu'un catalogue !
INSERT INTO `catalogue` (`id`, `titre`, `famille`, `categorie`, `cat_option`, `planche`, `fichier`, `ordre`) VALUES
(13, 'C2121', '7', '35,12,11,6,13,17,33', '7,13', 'C2121.jpg', 'PL-1060.pdf', 6),
(38, 'C7000', '15', '36,11,13,32', '13', 'logo-de-droite-haut_2.png', 'PL-0060.pdf', 0),
(12, 'C2030', '7', '35,11,20,3,13,33', '7,13', 'C2030.jpg', 'PL-1030.pdf', 5),
(7, 'C2022', '7', '35,11,6,13,17,33', '7,8,9,10,13,5', 'C2022.jpg', 'PL-1000.pdf', 1),
(9, 'C2024', '7', '35,11,6,13,16,17,33', '7,13', 'C2024.jpg', 'PL-0100.pdf', 2),
(11, 'C2028', '7', '35,11,6,13,16,18,33', '7,13', 'C2028.jpg', 'PL-1020.pdf', 4),
(10, 'C2027', '7', '35,11,6,25,13,16,17,33', '7,13', 'C2027.jpg', 'PL-1010.pdf', 3),
(14, 'C2124', '7', '35,12,11,6,13,16,17,33', '7,13', 'C2124.jpg', 'PL-1060_1.pdf', 7),
(15, 'C2125', '7', '35,12,11,6,25,13,17,33', '7,13', 'C2125.jpg', 'PL-1010_1.pdf', 8),
(16, 'C2131', '7', '35,12,11,21,20,3,13,33', '7,13', 'C2131.jpg', 'PL-1030_1.pdf', 9),
(17, 'C2141', '7', '35,12,11,27,6,13,17,33', '7,13', 'C2141.jpg', 'PL-1040.pdf', 10),
(18, 'C2142', '7', '35,12,11,27,6,13,17,33', '7,13', 'C2142.jpg', 'PL-1040_1.pdf', 11),
(19, 'C2146', '7', '35,12,11,6,19,33,15', '7,13', 'C2146.jpg', 'PL-1050.pdf', 12),
(20, 'C2147', '7', '35,12,11,6,13,19,33', '7,13', 'C2147.jpg', 'PL-1055.pdf', 13),
ce sont quelques exemples.

table catégories :
INSERT INTO `catalogue_cat` (`id`, `titre`, `image`) VALUES
(3, 'categorie1', ''),
(4, 'categorie2', ''),
(5, 'categorie3', ''),
(6, 'categorie5', ''),

etc...

les catégories ne sont pas stockés dans la table catalogue, c'est l'id des catégories qui est dans un champs de la table catalogue, pour la relation justement (mais comme tu dis, je dois m'être trompé...)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

18 févr. 2010, 15:54

Oui effectivement tu t'es un peu trompé :)

Garde ça comme ligne de conduite : on ne stocke JAMAIS plusieurs valeurs dans une même colonne. Si tu es amené à faire ça, c'est qu'il y a un problème.

Ici on identifie les entités suivantes : catalogue, catégorie, article, option. Si tu n'as qu'un seul catalogue à la rigueur tu pourrais ne pas en tenir compte et ne pas gérer ça. Mais allons-y, ça fera un exemple en plus et cela laisse la possibilité d'ajouter des catalogues facilement.

Ensuite, on rédige les règles de gestion (que tu corrigeras si ça ne correspond pas à la réalité, mais pour une boutique c'est ce qui me paraît le plus logique) :
1 catégorie appartient à 1 ou plusieurs catalogues.
1 catalogue contient 1 ou plusieurs catégories.
==> cela nous donne une relation n,n entre catalogues et catégories ===> on a besoin d'une relation entre les deux

1 article appartient à 1 et une seul catégorie.
1 catégories contient 1 ou plusieurs articles.
==> relation 1,n ===> pas de table de relation, on stocke l'identifiant de la catégorie qui contient l'article, dans l'entité article.

1 option peut être attribuée à 1 ou plusieurs articles.
1 article peut avoir 1 ou plusieurs options.
==> n,n ===> relation entre les deux

ce qui nous donnerait pour les tables :
Catalogues(pk_catalogue, libellé_catalogue) ==> entité
est_compose_de(fk_catalogue, fk_categorie) ==> relation
Categories(pk_categorie, libelle_categorie) ==> entité
Articles(pk_article, libelle_article, prix, description, fk_categorie) ==> entité
possede(fk_article, fk_option) ==> relation
Options(pk_option, libelle_option) ==> entité

Ici : PK = Primary key, FK = FK = Foreign key (référence vers une autre entité/table)

Petite variante :
Si une catégorie ne compose qu'un et un seul catalogue, alors cette fois pas de relation. On prend l'identifiant de l'entité source (Catalogue) que l'on met dans l'entité cible (Categorie). Ce qui donne :
Catalogues(pk_catalogue, libellé_catalogue)
Categories(pk_categorie, libelle_categorie, fk_catalogue) ==> la colonne fk_catalogue peut être mise ici car elle ne contiendra qu'une seule valeur, l'identifiant du catalogue qui contient la catégorie.

Voilà comment on décompose une base de données. Ainsi, il sera beaucoup plus facile de consulter les données, faire des calculs, des regroupements. Ou de les modifier, par exemple passer un article d'une catégorie à une autre.

Avec ce que tu as pour le moment, j'aimerais bien savoir comment tu vas me sortir les articles qui appartiennent à la catégorie numéro 12.
Et comment tu vas me bouger l'article 26 de la catégorie 12 vers la catégorie 27 nouvellement créée par exemple. C'est faisable, mais ce sera bien galère :)



Les puristes de Merise seront tolérant sur le vocabulaire, c'est un peu loin donc j'ai oublié mais le principe est là.


Sérieux, lis les docs dessus et refais ton modèle, ça va t'ennuyer un peu mais tu verras que tu y gagneras.

Petit nouveau ! | 8 Messages

19 févr. 2010, 02:42

Oui effectivement tu t'es un peu trompé :)

Avec ce que tu as pour le moment, j'aimerais bien savoir comment tu vas me sortir les articles qui appartiennent à la catégorie numéro 12.
Et comment tu vas me bouger l'article 26 de la catégorie 12 vers la catégorie 27 nouvellement créée par exemple. C'est faisable, mais ce sera bien galère :)
Merci pour ce cours magistral ! c'est vraiment sympa!

ok je vais me taper de la doc ces prochains jours!

pour l'instant, je gère tout ça assez facilement (à part le problème exposé).
j'ai un formulaire de modification des articles. dans ce formulaire, toutes les catégories apparaissent comme case à cocher. en cochant ou décochant, ça rajoute l'id de la catégorie dans le champs (valeurs séparées par des virgules).