Clé étrangère sous php My Admin

Résolu/Fermé
maffiou Messages postés 37 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 9 mai 2013 - 10 avril 2013 à 12:33
maffiou Messages postés 37 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 9 mai 2013 - 9 mai 2013 à 16:53
Bonjour,

En dernier recours, je me tourne vers ce forum pour enfin trouver une solution à mon problème. Cela fait de longues heures que je cherche vainement des topics similaires à celui que je suis en train de faire, sur commentçamarche.net et autres ... je suis notamment tombé sur celui-ci : https://forums.commentcamarche.net/forum/affich-7757933-cle-etrangere-avec-phpmyadmin mais après plusieurs tests, mon problème persiste.

Ce fameux problème est le suivant :
Tout d'abord, il faut savoir que je travaille sous phpMyAdmin comme l'indique le titre.
J'ai deux tables : categorieselements et elements.
categorieselements possède une clé primaire : idCategorie
elements possède une clé primaire : idElement

Je cherche à créer une clé étrangère dans la table elements qui ferait référence à la clé primaire idCategorie.
Pour cela, j'ai créé une nouvelle colonne dans ma table elements, puis je lui ai ajouté un index "INDEX" (sur certains forums des personnes disaient qu'il fallait ajouter un index "UNIQUE", cependant si je fais cela, je ne pourrais avoir plusieurs elements, dans ma table elements, qui possède un même idCategorie, alors que je souhaite que le cas se produise). Une fois cet index ajouté, je suis allé dans "Gestion des relations" dans ma table elements, j'ai déroulé le menu à côté d'idCategorie et ai choisi la clé primaire idCategorie de la table categorieselements (pour lui faire référence). Je ne me suis pour l'instant pas préoccupé des onDelete et onUpdate car cela viendra plus tard. J'exécute et une erreur de type : "Cannot add or update a child row: a foreign key constraint fails" apparaît.

Je ne comprends pas mon erreur et souhaiterais que vous m'expliquiez la démarche typique à suivre lorsque l'on veut créer une clé étrangère sous phpMyAdmin. De nombreux sites l'expliquent mais je me retrouve toujours heurté à cette erreur.

Je précise que mes deux tables utilisent le moteur "InnoDB" et que les clés idCategorie et idElement sont bien indexées "PRIMAIRE".

Merci pour votre aide,
Cordialement,
Maffiou.

A voir également:

4 réponses

Kaldoran Messages postés 137 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 21 juin 2015 29
Modifié par Kaldoran le 10/04/2013 à 23:26
Il est possible que tu ai une " violation " de la clef étrangere que tu essaye d'appliquer.
Sachant qu'elle sont en Innobd a la création de ta clef étrangère il essayera de vérifier tout les tuples ;

Si un n'est pas correct il ne créera pas la clef étrangère.

Voici un exemple :

Tu a une tabl qui contient :

1
2
3
comme Id,
Puis une seconde avec
1
2
4
Et tu essaye de faire une foreign key de la premiere sur la seconde , dans se cas la elle pourra pas etre crée car 4 ne fait pas parti de la premiere table.

Verifie que tu n'est pas d'erreur de se type.

Autre truc :

Verifie que la Foreign key s'applique bien sur 2 colonnes de meme type :
Ex : un INT vers un INT
Tu ne peux pas crée de clef étrangere d'un INT vers un VARCHAR par exemple
1
maffiou Messages postés 37 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 9 mai 2013 1
13 avril 2013 à 16:28
Bonjour,

Tout d'abord merci de ta réponse Kaldoran. Je n'ai pas répondu avant pour être sûr de ce que j'allais de nouveau avancer.

Sachant que :
- la clé étrangère "idCategorie" s'appliquait bien sur deux colonnes de même type, à savoir INT.
- les deux tables étaient en InnoDB

Je me suis concentré sur ta première remarque mais à vrai dire je ne l'ai pas bien comprise ... Quel est le rapport entre l'id (idElement) de la table elements et l'id de la table categorieselements ?

Toujours est-il que j'ai décidé de vider mes deux tables de leur contenu pour recréer ma clé étrangère et cela a fonctionné ! La colonne idCategorie dans la table elements est bien clé étrangère en référence à idCategorie de categorieselements. Ainsi, les mises à jour (grâce à onDelete SET NULL et onUpdate Cascade) se font correctement.

Malheureusement, je me trouve aujourd'hui devant un autre problème : celui de vouloir créer un couple de clé à la fois primaires et étrangères.

Ma table elements accueillant une liste d'entrées/plats/desserts/boissons et ma table menus (dont je n'ai pas encore parlé) accueillant la liste des menus (nom et prix notamment), je souhaite pouvoir en une requête pouvoir afficher sur mon site l'intégralité d'un menu en particulier. Il me fait alors une table qui recense de quels éléments un menu est-il composé. Au vu des cardinalités maximales à n entre les tables menus et éléments, une table associative se doit d'être créée : j'ai nommé "compomenus".

La règle veut donc que les clés primaires des tables elements et menus (idElement et idMenu) forment un couple de clés primaires dans cette table compomenus. De plus, il faut que ce couple de clés se mette à jour si l'id d'un menu vient par exemple à changer. Je souhaite donc que ce couple soit également clé étrangère.

J'ai procédé comme suit :
- création de la table compoMenus
- création des colonnes idMenu et idElement, toutes deux primaires et de type INT
- dans la gestion des relations et pour chacun des id, référence à la clé primaire de la table menus et à celle d'elements. Ajout d'un onUpdate Cascade (pas de onDelete pour le moment).

Sachant que l'idMenu ne sera pas unique (plusieurs lignes seront de type : idMenu1 --> idElement4, idMenu1 --> idElement17, ...) et que l'idElement lui le sera, j'ai décidé d'ajouter un index "UNIQUE" à idMenu et "INDEX" à idElement.

À l'heure actuelle, ces tables ne se remplissent pas alors que le code situé dans mon script PHP ne retourne pas d'erreur et après plusieurs tests semble correct.

Ma question est alors la suivante : est-ce que la procédure que je vient d'évoquer pour créer un couple de clés primaires/étrangères n'est pas bonne ?
Si c'est le cas, quelle est la bonne ?

Merci beaucoup pour votre aide,
Cordialement,
Maffiou
0
Kaldoran Messages postés 137 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 21 juin 2015 29
26 avril 2013 à 18:51
Bonjour ,
et désolé d'avoir mis autant de temps pour vous répondre ;

Pourriez vous S'il vous plait poster la structure de vos 2 tables.

Petite question ,
pourquoi ne pas fait une simple requetes SQL qui récupère le contenu de la table ELement tout en associant les valeurs contenu dans la table Menus ;

un simple SELECT * FROM Element,Menus WHERE id_element = id_menu_rechercher
0
maffiou Messages postés 37 Date d'inscription mercredi 20 février 2008 Statut Membre Dernière intervention 9 mai 2013 1
9 mai 2013 à 16:53
Bonjour,

Tout d'abord, je tiens à m'excuser de ne pas avoir répondu plus tôt, en effet, n'ayant pas eu de réponses durant un peu moins de deux semaines (j'ai reçu votre message privé Kaldoran mais ne l'ai lu qu'aujourd'hui, n'étant pas retourné sur CCM depuis ...).
Ma question découlait d'un projet que je devais effectuer dans le cadre scolaire et rendre le 17 avril, voila pourquoi j'ai oublié de me rendre sur le forum après cette date ...

Pour respecter la charte "d'éthique" d'un forum qui veut que l'on ne laisse pas mourir un sujet sans solution (surtout quand celle-ci découle de l'auteur), je vais tâcher d'expliquer brièvement la procédure que j'ai suivi et qui a abouti au bon fonctionnement de ma BDD.

J'ai procédé comme suit et tout a alors correctement fonctionné :

- j'ai vidé mes deux tables : elements et menus pour ne pas avoir de soucis avec des valeurs d'id que ne renvoient à rien dans l'autre table.
- création de la table compoMenus
- création des colonnes idMenu et idElement, toutes deux primaires et de type INT avec un Index "INDEX" sur les deux id.
- dans la gestion des relations et pour chacun des id, référence à la clé primaire de la table menus et à celle d'elements. Ajout d'un onUpdate Cascade et d'un onDelete Cascade également.

Sujet pouvant être fermé.

Cordialement,
maffiou.
0