J'essaie de transférer l'ingénierie de mon nouveau schéma sur mon serveur de base de données, mais je ne comprends pas pourquoi j'obtiens cette erreur. J'ai essayé de chercher la réponse ici, mais tout ce que j'ai trouvé a dit de définir le moteur de base de données sur Innodb ou de vérifier 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. Toute autre aide que vous pourriez offrir?
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
Exécution du script SQL terminée: instructions: 7 réussies, 1 échouée
Voici le code SQL pour les tables parent.
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
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 parent sont INT UNSIGNED
?
Ils doivent correspondre exactement au même type de données dans les deux tables.
Raisons pour lesquelles vous pouvez obtenir une erreur de contrainte de clé étrangère:
Mettre à jour:
ON DELETE SET NULL
n'est pas définie comme étant null. Assurez-vous donc que la colonne est définie sur null par défaut.Vérifiez ces.
Pour d'autres, la même erreur peut ne pas toujours être due à une incompatibilité de type de colonne, vous pouvez en savoir plus sur une erreur de clé mysql foriegn en émettant une commande
SHOW ENGINE INNODB STATUS;
vous pouvez trouver une erreur près du haut du message imprimé quelque chose comme
Impossible de trouver un index dans la table référencée où le les colonnes référencées apparaissent en tant que premières colonnes ou types de colonnes dans la table et la table référencée ne correspondent pas pour la contrainte.
L'erreur 1215 est ennuyeuse. La réponse de la pilule d'explosion couvre les bases. Vous voulez vous assurer de commencer à partir de là. Cependant, il y a plus, beaucoup plus de cas subtils à surveiller:
Par exemple, lorsque vous essayez de relier des clés PRIMARY KEY de différentes tables, veillez à fournir les options ON UPDATE
et ON DELETE
appropriées. Par exemple.:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
ne volera pas, car les clés primaires (telles que id
) ne peuvent pas être NULL
.
Je suis convaincu que l'ajout de ce type de contraintes pose des problèmes encore plus subtils et similaires. C'est pourquoi, lorsque vous rencontrez des erreurs de contrainte, veillez toujours à ce que les contraintes et leurs implications aient un sens dans votre contexte actuel. Bonne chance avec votre erreur 1215!
Vérifiez le classement des tables à l’aide de SHOW TABLE STATUS
, vous pouvez vérifier les informations relatives aux tables, y compris le classement.
Les deux tables doivent avoir le même classement.
Il m'est arrivé
Dans mon cas, j'avais supprimé une table en utilisant SET FOREIGN_KEY_CHECKS=0
, puis SET FOREIGN_KEY_CHECKS=1
après. Quand je suis allé recharger la table, j'ai eu error 1215
. Le problème était qu'il y avait une autre table dans la base de données qui avait une clé étrangère à la table que j'avais supprimée et rechargée. Une partie du processus de rechargement impliquait la modification d'un type de données pour l'un des champs, ce qui rendait la clé étrangère de l'autre table invalide, déclenchant ainsi error 1215
. J'ai résolu le problème en supprimant puis en rechargeant l'autre table avec le nouveau type de données pour le champ concerné.
Il y a un écueil que j'ai rencontré avec "Erreur 1215: impossible d'ajouter une contrainte de clé étrangère" lors de l'utilisation de Laravel 4, en particulier 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 tableaux un par un, ce qui signifie que chaque fichier de migration génère un tableau . Vous devez être conscient du fait que chaque fichier de migration est généré avec un horodatage dans le nom du fichier, qui donne un ordre aux fichiers. L'ordre de génération est également l'ordre d'opération de migration lorsque vous lancez la commande Artisan CLI "php artisan migrate" . Ainsi, si un fichier demande une contrainte de clé étrangère faisant référence à une clé qui sera, mais pas encore, généré dans un dernier fichier, l'erreur 1215 est déclenchée . Dans ce cas, vous devez 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.
J'ai eu la même erreur en essayant d'ajouter un fk. Dans mon cas, le problème était dû à la PK de la table FK qui était marquée comme non signée.
Une autre raison: si vous utilisez ON DELETE SET NULL
toutes les colonnes utilisées dans la clé étrangère, vous devez autoriser les valeurs NULL. Quelqu'un d'autre l'a découvert dans cette question .
D'après ce que j'ai compris, l'intégrité des données ne poserait pas de problème, mais il semble que MySQL ne supporte tout simplement pas cette fonctionnalité (en 5.7).
Vérifiez la compatibilité des tables. Par exemple, si l'une des tables est MyISAM
et l'autre InnoDB
, vous pouvez avoir ce problème.
Pour MySQL (INNODB) ..., obtenez les définitions des colonnes que vous souhaitez lier.
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name','referenced_table_name') AND
COLUMN_NAME IN ('col_name','referenced_col_name')\G
comparer et vérifier les deux définitions de colonne ont
même COLUMN_TYPE (longueur), même COLATION
pourrait être utile de jouer comme
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
Je ne trouve pas cette erreur
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
Cela se produit également lorsque le type des colonnes n'est pas le même.
par exemple. Si la colonne à laquelle vous faites référence est UNSIGNED INT et que la colonne à laquelle vous faites référence est INT, vous obtenez cette erreur.
j'ai eu le même problème, ma solution:
Avant:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solution:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);
J'espère que c'est de l'aide;)
J'ai vécu cette erreur pour une raison complètement différente. J'ai utilisé MySQL Workbench 6.3 pour créer mon modèle de données (outil génial). J'ai remarqué que lorsque l'ordre des colonnes défini dans la définition de contrainte de clé étrangère ne correspond pas à la séquence des colonnes du tableau, cette erreur est également générée.
Cela m'a pris environ 4 heures pour essayer tout le reste mais vérifier cela.
Maintenant tout fonctionne bien et je peux revenir au codage. :-)
Wooo je viens de l'obtenir! C'était un mélange de beaucoup de réponses déjà postées (innoDB, non signé, etc.). Cependant, une chose que je n’ai pas vue ici est la suivante: si votre FK pointe sur une PK, assurez-vous que la colonne source a une valeur qui a du sens. Par exemple, si la PC est un mediumint (8), assurez-vous que la colonne source contient également un mediumint (8). Cela faisait partie du problème pour moi.
Pour moi, c'était les types de colonne. BigINT! = INT.
Mais alors cela n'a toujours pas fonctionné.
Alors j'ai vérifié les moteurs. Assurez-vous que Table1 = InnoDB et Table = InnoDB
Lorsque cette erreur se produit car la table référencée utilise le moteur MyISAM, cette réponse permet de convertir rapidement votre base de données. Toutes les tables de modèles Django utilisent donc InnoDB: https://stackoverflow.com/a/15389961/2950621
C'est une commande de gestion Django appelée convert_to_innodb.
Je voulais juste ajouter ce cas aussi pour la relation VARCHAR
clé étrangère. J'ai passé la semaine dernière à essayer de comprendre cela dans MySQL Workbench 8.0 et j'ai finalement réussi à corriger l'erreur.
Réponse courte: Le jeu de caractères et le classement du schéma, de la table, de la colonne, de la table de référence, de la colonne de référence et de toute autre table faisant référence à la table parente doivent correspondre.
Réponse longue: J'avais un type de données ENUM dans mon tableau. J'ai changé ceci en VARCHAR
et je peux obtenir les valeurs d'une table de référence afin de ne pas avoir à modifier la table parent pour ajouter des options supplémentaires. Cette relation clé étrangère semblait simple, mais j'ai une erreur 1215. La réponse de arvind et la suivante link suggèrent l’utilisation de
SHOW ENGINE INNODB STATUS;
En utilisant cette commande, j'ai reçu la description détaillée de l'erreur, sans information utile supplémentaire.
Impossible de trouver un index dans la table référencée où le les colonnes référencées apparaissent en tant que premières colonnes ou types de colonnes dans la table et la table référencée ne correspondent pas pour la contrainte. Notez que le type de stockage interne ENUM et SET a changé dans les tables créées avec> = InnoDB-4.1.12, et les colonnes de ce type dans les anciennes tables ne peuvent pas être référencés par de telles colonnes dans les nouvelles tables. Veuillez vous référer à http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html pour obtenir la définition correcte de la clé étrangère.
Après quoi, j’ai utilisé SET FOREIGN_KEY_CHECKS=0;
comme suggéré par Arvind Bharadwaj et le lien ici :
Cela a donné le message d'erreur suivant:
Code d'erreur: 1822. Impossible d'ajouter la contrainte de clé étrangère. Manquant index pour contrainte
À ce stade, j'ai «ingénierie inverse» le schéma et j'ai pu créer la relation de clé étrangère dans le diagramme EER. En 'forward engineering'-ing, j'ai eu l'erreur suivante:
Erreur 1452: Impossible d'ajouter ou de mettre à jour une ligne enfant: contrainte de clé étrangère échoue
Lorsque j'ai transféré le diagramme EER à un nouveau schéma, le script SQL s'est exécuté sans problème. En comparant le code SQL généré à partir des tentatives de transfert d'ingénieur, j'ai constaté que la différence résidait dans le jeu de caractères et le classement. La table parent, la table enfant et les deux colonnes contenaient le jeu de caractères utf8mb4
et le classement utf8mb4_0900_ai_ci
; toutefois, une autre colonne de la table parent a été référencée à l'aide de CHARACTER SET = utf8 , COLLATE = utf8_bin ;
dans une autre table enfant.
Pour l'ensemble du schéma, j'ai modifié le jeu de caractères et le classement de toutes les tables et de toutes les colonnes comme suit:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
Cela a finalement résolu mon problème avec l'erreur 1215.
Côté Remarque: Le classement utf8mb4_general_ci
fonctionne dans MySQL Workbench version 5.0 ou ultérieure. La collation utf8mb4_0900_ai_ci
ne fonctionne que pour MySQL Workbench 8.0 ou supérieur. Je pense qu'une des raisons pour lesquelles j'ai eu des problèmes avec le jeu de caractères et le classement est due à la mise à niveau de MySQL Workbench vers la version 8.0 entre les deux. Voici un link qui en dit plus sur cette collation.
Dans mon cas, j'ai dû désactiver les contrôles FOREIGN KEY
car les tables sources n'existaient pas.
SET FOREIGN_KEY_CHECKS=0;
Ceci est une version subtile de ce qui a déjà été dit, mais dans mon cas, j'avais 2 bases de données (foo et bar). J'ai d'abord créé foo et je n'ai pas réalisé qu'il faisait référence à une clé étrangère dans bar.baz (qui n'a pas encore été créée). Lorsque j'ai essayé de créer bar.baz (sans clé étrangère), j'ai continué à avoir cette erreur. Après avoir regardé pendant un moment, j'ai trouvé la clé étrangère dans foo.
Donc, si vous obtenez cette erreur, vous pouvez avoir une clé étrangère préexistante à la table en cours de création.
Soyez conscient de l'utilisation des citations arrière aussi. J'ai eu dans un script la déclaration suivante
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
mais les citations à la fin étaient fausses. Cela aurait dû être:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL ne donne malheureusement pas de détails sur cette erreur ...
Je sais que je suis très tard pour la fête mais je veux le mettre ici pour qu'il soit listé.
En plus de tous les conseils ci-dessus pour vous assurer que les champs sont définis de manière identique et que les types de table ont le même classement, veillez à ne pas commettre l'erreur de recrue en essayant de lier des champs lorsque les données du champ CHILD ne sont pas déjà dans le champ PARENT. Si vous avez des données dans le champ ENFANT que vous n'avez pas encore entrées dans le champ PARENT, cela provoquera cette erreur. C'est dommage que le message d'erreur ne soit pas un peu plus utile.
En cas de doute, sauvegardez la table contenant la clé étrangère, supprimez toutes les données, puis essayez de créer la clé étrangère. En cas de succès, alors que faire?
Bonne chance.
Pour moi, l'erreur 1215 s'est produite lors de l'importation d'un fichier de vidage créé par mysqldump
, qui crée les tables par ordre alphabétique, ce qui a amené dans mon cas des clés étrangères à faire référence à des tables créées ultérieurement dans le fichier. (Accessoires à cette page pour le signaler: https://www.percona.com/blog/2017/04/06/dealing-mysql-error-code-1215-cannot-add-foreign-key-constraint/ )
Puisque mysqldump ordonne les tables par ordre alphabétique et que je ne veux pas changer les noms des tables, j'ai suivi les instructions de la réponse de JeremyWeir sur cette page , qui indique de mettre set FOREIGN_KEY_CHECKS = 0;
en haut du fichier de vidage et de mettre SET FOREIGN_KEY_CHECKS = 1;
à le bas du fichier de vidage.
Cette solution a fonctionné pour moi.
Une autre source de cette erreur est que vous avez 2 ou plusieurs noms de table identiques qui portent les mêmes noms de clés étrangères. Cela arrive parfois aux personnes qui utilisent des logiciels de modélisation et de conception, tels que Mysql Workbench, et qui génèrent ultérieurement le script à partir de la conception.
Ajouter une autre raison à @ Les pilules d'explosion répondent ci-dessus :
7- Lors de l'utilisation de clés multi-colonnes, l'ordre dans la création de la clé étrangère doit correspondre à l'autre dans l'ordre des colonnes du tableau.