382 votes

Erreur MySQL 1215 : Impossible d'ajouter une contrainte de clé étrangère

J'essaie de transférer mon nouveau schéma sur mon serveur de données, mais je n'arrive pas à comprendre pourquoi j'obtiens cette erreur. J'ai essayé de chercher la réponse ici, mais tout ce que j'ai trouvé m'a dit soit de définir le moteur de base de données sur Innodb, soit de m'assurer que les clés que j'essaie d'utiliser comme clé étrangère sont des clés primaires dans leurs propres tables. J'ai fait ces deux choses, si je ne me trompe pas. Avez-vous une autre aide à proposer ?

Executing SQL script in server

ERROR: Error 1215: Cannot add foreign key constraint

-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
  `Clients_Case_Number` INT NOT NULL ,
  `Staff_Emp_ID` INT NOT NULL ,
  PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
  INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
  INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
  CONSTRAINT `fk_Clients_has_Staff_Clients`
    FOREIGN KEY (`Clients_Case_Number` )
    REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Clients_has_Staff_Staff1`
    FOREIGN KEY (`Staff_Emp_ID` )
    REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

L'exécution de SQL script est terminée : déclarations : 7 ont réussi, 1 a échoué

Voici le SQL pour les tables parentes.

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
  `Case_Number` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  `Address` CHAR(50) NULL ,
  `Phone_Number` INT(10) NULL ,
  PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
  `Emp_ID` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB

7 votes

Veuillez afficher le schéma des tables parentes : Clients y Staff .

0 votes

1 votes

@Denis ce n'est probablement pas un doublon puisque l'OP dit qu'ils ont vérifié que les colonnes sont des PKs dans les tables parentes.

674voto

Ike Walker Points 21162

Je suppose que Clients.Case_Number et/ou Staff.Emp_ID ne sont pas exactement le même type de données que Clients_has_Staff.Clients_Case_Number et Clients_has_Staff.Staff_Emp_ID .

Peut-être que les colonnes dans les tables parentes sont INT UNSIGNED ?

Ils doivent être exactement du même type de données dans les deux tables.

12 votes

Merci. C'est ce qui s'est avéré être le problème. Staff.Emp_ID était un SMALLINT, alors que la colonne de référence était un INT. Parfois, ce sont les petites choses...

0 votes

Tks. Dans mon cas, j'avais accidentellement cliqué sur "ZeroFill" sur la clé étrangère dans la table enfant, ce qui signifie qu'elle ne correspondait pas exactement à la colonne de la table parent.

12 votes

Il se peut également que le jeu de caractères soit différent. J'ai eu ce problème où une colonne avait le jeu de caractères utf8 alors que l'autre avait latin1. Facile à résoudre avec ALTER TABLE Table CHARACTER SET = utf8 ; et ALTER TABLE Device CHANGER DE COLONNE ID ID CHAR(36) CHARACTER SET 'utf8' NOT NULL ;

288voto

Explosion Pills Points 89756

Raisons pour lesquelles vous pouvez obtenir une erreur de constraing de clé étrangère :

  1. Vous n'utilisez pas InnoDB comme moteur sur toutes les tables
  2. Vous essayez de référencer une clé inexistante sur la table cible. Assurez-vous qu'il s'agit d'une clé sur l'autre table (il peut s'agir d'une clé primaire ou unique)
  3. Les types des colonnes ne sont pas les mêmes (à l'exception de la colonne de la table de référence qui peut être nulle).

Vérifie ça.

17 votes

J'ajouterai juste que si le FK est sur une colonne de caractères, je pense qu'ils doivent être du même jeu de caractères et de la même collation. (Ou peut-être que les charsets 1-byte et 2-byte ne sont pas compatibles).

0 votes

Une réponse simple et efficace ! Tous ceux qui déboguent l'erreur 1215 devraient commencer par là. J'ai ajouté quelques cas plus subtils à surveiller. si votre erreur n'est pas due à l'un de ces points.

10 votes

Ma raison est que vous avez souligné le premier point "Différents moteurs de BD pour deux tables, InnoDB et MyISAM".

101voto

arvind Points 21

Pour d'autres, la même erreur n'est pas toujours due à une incompatibilité de type de colonne, vous pouvez obtenir plus d'informations sur une erreur de clé forieg de mysql en lançant la commande

MONTRER L'ÉTAT DU MOTEUR INNODB ;

vous trouverez peut-être une erreur en haut du message imprimé, du genre

Impossible de trouver un index dans la table référencée où les colonnes référencées apparaissent comme les premières colonnes, ou les types de colonne dans la table et la table référencée ne correspondent pas pour la contrainte.

13 votes

C'est la meilleure réponse, je pense, car elle aide au diagnostic ! Merci.

1 votes

Comment cela devrait-il fonctionner ? Exécuter les deux requêtes à la suite ?

0 votes

@C4u, oui nous devrions exécuter les deux requêtes dans une rangée en ayant SHOW ENGINE INNODB STATUS en premier et ensuite suivi par les autres requêtes.

6voto

user2975399 Points 41

Il y a un écueil que j'ai rencontré avec "Error 1215 : Cannot add foreign key constraint" lorsque vous utilisez Laravel 4, notamment avec les générateurs Laravel 4 de JeffreyWay.

Dans Laravel 4, vous pouvez utiliser les générateurs de JeffreyWay pour générer des fichiers de migration afin de créer des tables une par une, ce qui signifie que chaque fichier de migration génère une table. Vous devez être conscient du fait que chaque fichier de migration est généré avec un horodatage dans le nom du fichier, ce qui donne un ordre aux fichiers. L'ordre de génération est également l'ordre de l'opération de migration lorsque vous lancez la commande CLI Artisan "php artisan migrate". Ainsi, si un fichier demande une contrainte de clé étrangère se référant à une clé qui sera, mais pas encore, générée dans un dernier fichier, l'erreur 1215 est déclenchée. Dans ce cas, ce que vous devez faire est d'ajuster l'ordre de génération des fichiers de migration. Générez les nouveaux fichiers dans le bon ordre, copiez le contenu, puis supprimez les anciens fichiers désordonnés.

5voto

Ali Points 21

J'ai eu la même erreur en essayant d'ajouter un fk. Dans mon cas, le problème était causé par le PK de la table FK qui était marqué comme non signé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X