MySQL Ne Peut Pas Ajouter De Contrainte De Clé Étrangère
Donc j'essaye d'ajouter des contraintes de Clé Étrangère à ma base de données comme un projet de l'exigence et ça a marché une fois ou deux sur des tables différentes, mais j'ai deux tables sur lesquelles j'obtiens une erreur lorsque je tente d'ajouter les Contraintes de Clé Étrangère.
Le message d'erreur que je reçois est:
ERREUR 1215 (HY000): Impossible d'ajouter une contrainte de clé étrangère
C'est le SQL que j'utilise pour créer les tables, les deux offenser les tables sont Patient
et Appointment
.
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
CREATE SCHEMA IF NOT EXISTS `doctorsoffice` DEFAULT CHARACTER SET utf8 ;
USE `doctorsoffice` ;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`doctor`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`doctor` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`doctor` (
`DoctorID` INT(11) NOT NULL AUTO_INCREMENT ,
`FName` VARCHAR(20) NULL DEFAULT NULL ,
`LName` VARCHAR(20) NULL DEFAULT NULL ,
`Gender` VARCHAR(1) NULL DEFAULT NULL ,
`Specialty` VARCHAR(40) NOT NULL DEFAULT 'General Practitioner' ,
UNIQUE INDEX `DoctorID` (`DoctorID` ASC) ,
PRIMARY KEY (`DoctorID`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`medicalhistory`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`medicalhistory` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`medicalhistory` (
`MedicalHistoryID` INT(11) NOT NULL AUTO_INCREMENT ,
`Allergies` TEXT NULL DEFAULT NULL ,
`Medications` TEXT NULL DEFAULT NULL ,
`ExistingConditions` TEXT NULL DEFAULT NULL ,
`Misc` TEXT NULL DEFAULT NULL ,
UNIQUE INDEX `MedicalHistoryID` (`MedicalHistoryID` ASC) ,
PRIMARY KEY (`MedicalHistoryID`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`Patient`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`Patient` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`Patient` (
`PatientID` INT unsigned NOT NULL AUTO_INCREMENT ,
`FName` VARCHAR(30) NULL ,
`LName` VARCHAR(45) NULL ,
`Gender` CHAR NULL ,
`DOB` DATE NULL ,
`SSN` DOUBLE NULL ,
`MedicalHistory` smallint(5) unsigned NOT NULL,
`PrimaryPhysician` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`PatientID`) ,
UNIQUE INDEX `PatientID_UNIQUE` (`PatientID` ASC) ,
CONSTRAINT `FK_MedicalHistory`
FOREIGN KEY (`MEdicalHistory` )
REFERENCES `doctorsoffice`.`medicalhistory` (`MedicalHistoryID` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `FK_PrimaryPhysician`
FOREIGN KEY (`PrimaryPhysician` )
REFERENCES `doctorsoffice`.`doctor` (`DoctorID` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`Appointment`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`Appointment` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`Appointment` (
`AppointmentID` smallint(5) unsigned NOT NULL AUTO_INCREMENT ,
`Date` DATE NULL ,
`Time` TIME NULL ,
`Patient` smallint(5) unsigned NOT NULL,
`Doctor` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`AppointmentID`) ,
UNIQUE INDEX `AppointmentID_UNIQUE` (`AppointmentID` ASC) ,
CONSTRAINT `FK_Patient`
FOREIGN KEY (`Patient` )
REFERENCES `doctorsoffice`.`Patient` (`PatientID` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `FK_Doctor`
FOREIGN KEY (`Doctor` )
REFERENCES `doctorsoffice`.`doctor` (`DoctorID` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`InsuranceCompany`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`InsuranceCompany` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`InsuranceCompany` (
`InsuranceID` smallint(5) NOT NULL AUTO_INCREMENT ,
`Name` VARCHAR(50) NULL ,
`Phone` DOUBLE NULL ,
PRIMARY KEY (`InsuranceID`) ,
UNIQUE INDEX `InsuranceID_UNIQUE` (`InsuranceID` ASC) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `doctorsoffice`.`PatientInsurance`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `doctorsoffice`.`PatientInsurance` ;
CREATE TABLE IF NOT EXISTS `doctorsoffice`.`PatientInsurance` (
`PolicyHolder` smallint(5) NOT NULL ,
`InsuranceCompany` smallint(5) NOT NULL ,
`CoPay` INT NOT NULL DEFAULT 5 ,
`PolicyNumber` smallint(5) NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`PolicyNumber`) ,
UNIQUE INDEX `PolicyNumber_UNIQUE` (`PolicyNumber` ASC) ,
CONSTRAINT `FK_PolicyHolder`
FOREIGN KEY (`PolicyHolder` )
REFERENCES `doctorsoffice`.`Patient` (`PatientID` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `FK_InsuranceCompany`
FOREIGN KEY (`InsuranceCompany` )
REFERENCES `doctorsoffice`.`InsuranceCompany` (`InsuranceID` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
USE `doctorsoffice` ;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
Vous devez vous connecter pour publier un commentaire.
À trouver l'erreur exécuter ceci:
Et de regarder dans la
LATEST FOREIGN KEY ERROR
section.Le type de données pour l'enfant de la colonne doit correspondre à la colonne parent exactement. Par exemple, depuis
medicalhistory.MedicalHistoryID
est unINT
,Patient.MedicalHistory
doit aussi être unINT
, pas unSMALLINT
.Aussi, vous devez exécuter la requête
set foreign_key_checks=0
avant d'exécuter le DDL de sorte que vous pouvez créer les tables dans un ordre arbitraire, plutôt que de devoir créer toutes les tables parent devant les tables enfants.set null
sur supprimer, mais la colonne a éténot null
.-vvv --show-warnings
de s'exposer, que trop d'informations à la place de la concision de message d'erreur.varchar(100)
comme par défaut et j'ai manqué de la mettre à l'INT UNSIGNED
.J'avais mis un champ comme "Unsigned" et d'autres pas. Une fois que j'ai mis les deux colonnes non signé, il a travaillé.
Watchout: Même si vos tables ont le même Classement, les colonnes pouvait encore avoir un autre.
unique
à la table de référence colonne, même si c'est unPrimary Key
!!Essayez d'utiliser le même type de vos clés primaires - int(11) - sur les clés étrangères - smallint(5) - ainsi.
Espère que cela aide!
Confirmer que le codage des caractères et collation pour les deux tables est le même.
Dans mon propre cas, l'une des tables a l'aide de
utf8
et l'autre a été en utilisantlatin1
.J'ai eu un autre cas où le codage est le même, mais le classement différent. Un
utf8_general_ci
l'autreutf8_unicode_ci
Vous pouvez exécuter cette commande pour définir l'encodage et le classement pour une table.
J'espère que cela aide quelqu'un.
Pour définir une CLÉ ÉTRANGÈRE dans la Table B, vous devez définir une CLÉ dans la table A.
Dans le tableau A:
L'INDICE de
id
(id
)Et puis, dans le tableau B,
J'ai eu le même problème et la solution était très simple.
Solution : les clés étrangères a déclaré dans le tableau ne devrait pas imposer de ne pas être null.
de référence : Si vous spécifiez un SET NULL action, assurez-vous que vous n'avez pas déclaré les colonnes dans la table enfant comme not NULL. (ref
)
Veuillez vous assurer que les tableaux sont en InnoDB format. Même si l'on est au format MyISAM, ensuite, la contrainte de clé étrangère ne fonctionnent pas.
Aussi, une autre chose est que, les deux champs doivent être du même type. Si l'un est de type INT, alors l'autre doit également être de type INT. Si l'un est de type VARCHAR, l'autre doit également être de type VARCHAR, etc.
Vérifier les règles suivantes :
Vérifie d'abord si les noms qui sont donnés le droit pour les noms de table
Deuxième à droite, type de données donnent à la clé étrangère ?
J'ai affronté le problème et a pu le résoudre en faisant en sorte que les types de données ont été exactement la correspondance .
J'ai été en utilisant SequelPro pour l'ajout de la contrainte et de la clé primaire non signés par défaut .
Vérifier la signature sur les deux colonnes de la table. Si la référence colonne du tableau est SIGNÉ, la table référencée colonne doit être SIGNÉ.
J'ai eu la même erreur lors de la création de la clé étrangère dans un de Nombreux de Nombreux de la table où la clé primaire est composé de 2 clés étrangères et un autre normal de la colonne. J'ai résolu le problème en modifiant la table référencée nom c'est à dire de la société, comme indiqué dans le code corrigé ci-dessous:
J'ai eu la même erreur avec deux clés étrangères pour les tables différentes mais avec les mêmes noms de clé! J'ai renommé les touches et l'erreur a disparu)
Eu une erreur similaire, mais dans mon cas, j'ai été absent de déclarer le pk que auto_increment.
Juste au cas où il pourrait être utile à tout le monde
J'ai eu le même message d'erreur. La cause dans mon cas était:
La cause: Depuis que j'ai utilisé phpmyadmin pour créer des clés étrangères dans le nouveau nom de la base de données - les clés étrangères ont été créés avec une base de données de préfixe de nom, mais le nom de la base de préfixe n'a pas été mis à jour. Donc il y avait encore des références dans le backup-db pointant vers le nouvellement créé db.
Ma solution est peut-être un peu gênant, et raconte l'histoire de pourquoi vous devriez parfois de regarder ce que vous avez en face de vous, au lieu de ces postes 🙂
J'avais couru à l'avant de l'ingénieur avant, qui a échoué, cela signifiait que ma base de données déjà eu une quelques tables, puis j'ai été assis à essayer de réparer les contraintes de clé étrangère échecs en essayant de s'assurer que tout était parfait, mais il a couru contre les tables précédemment créé, donc c'était pas de l'emporter.
Une autre cause de cette erreur, c'est quand vos tables ou de colonnes contiennent réservés mots-clés:
Parfois on ne les oublie.
Dans mon cas, il y a une erreur de syntaxe qui n'a pas été explicitement informé par MySQL console lors de l'exécution de la requête. Cependant,
SHOW ENGINE INNODB STATUS
de la commandeLATEST FOREIGN KEY ERROR
section signalé,Je me devais de laisser un espace entre
REFERENCES
etrole
pour le faire fonctionner.Pour moi, le problème était, ma table parent avait le jeu de caractères différent de celui auquel j'étais en train de créer.
Table Parent (PRODUITS)
Table enfant qui a un problème (PRICE_LOGS)
MODIFIÉ POUR
Mon problème était que j'étais en essayant de créer la table de relation avant les autres tables!
J'ai eu ce même problème, alors j'ai corrigé le nom du Moteur comme Innodb dans les deux tables parent et enfant et corrigé la référence nom du champ
LA CLÉ ÉTRANGÈRE (
c_id
) RÉFÉRENCESx9o_parent_table
(c_id
)puis il fonctionne très bien et les tables sont installées correctement. Ce sera l'utilisation complète de quelqu'un.