Итак, я пытаюсь добавить ограничения внешнего ключа к моей базе данных в качестве требования к проекту, и он работал впервые или два в разных таблицах, но у меня есть две таблицы, на которых я получаю сообщение об ошибке при попытке добавить внешний ключ Ограничения. Сообщение об ошибке, которое я получаю:
ОШИБКА 1215 (HY000): не удается добавить ограничение внешнего ключа
Это SQL, который я использую для создания таблиц, для двух таблиц: Patient
и 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;
Чтобы найти конкретную ошибку, выполните следующее:
SHOW ENGINE INNODB STATUS;
И посмотрите в разделе LATEST FOREIGN KEY ERROR
.
Тип данных для дочернего столбца должен точно соответствовать родительскому столбцу. Например, поскольку medicalhistory.MedicalHistoryID
является INT
, Patient.MedicalHistory
также должен быть INT
, а не SMALLINT
.
Кроме того, перед запуском DDL следует запустить запрос set foreign_key_checks=0
, чтобы вы могли создавать таблицы в произвольном порядке, а не создавать все родительские таблицы перед соответствующими дочерними таблицами.
Я установил одно поле как "Без знака", а другое - нет. Как только я установил оба столбца в Unsigned, он сработал.
unsigned
работала и для меня.
unique
столбец справочной таблицы, даже если это Primary Key
!!
Попробуйте использовать один и тот же тип ваших основных ключей - int (11) - на внешних ключах - smallint (5) - также.
Надеюсь, что это поможет!
Подтвердите, что кодировка символов и сопоставление для двух таблиц одинаковы.
В моем случае одна из таблиц использовала utf8
, а другая - latin1
.
У меня был другой случай, когда кодировка была одинаковой, но сортировка различна. Один utf8_general_ci
другой utf8_unicode_ci
Вы можете запустить эту команду, чтобы установить кодировку и сопоставление для таблицы.
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Я надеюсь, что это поможет кому-то.
Пожалуйста, убедитесь, что обе таблицы находятся в формате InnoDB. Даже если он находится в формате MyISAM, тогда ограничение внешнего ключа не будет работать.
Кроме того, другое дело, что оба поля должны быть одного типа. Если один из них INT, то другой должен также быть INT. Если один из VARCHAR, другой должен также быть VARCHAR и т.д.
Чтобы установить FOREIGN KEY в таблице B, вы должны установить KEY в таблице A.
В таблице A: INDEX id
(id
)
И затем в таблице B,
CONSTRAINT `FK_id` FOREIGN KEY (`id`) REFERENCES `table-A` (`id`)
У меня была такая же проблема, и решение было очень простым. Решение: внешние ключи, объявленные в таблице, не должны быть не равными нулю.
ссылка: если вы укажете действие SET NULL, убедитесь, что вы не объявили столбцы в дочерней таблице как NOT NULL. (ref )
Проверить следующие правила:
Сначала проверяется правильность присвоения имен именам таблиц
Второй правый тип данных дает внешнему ключу?
Проверьте подписывание обоих столбцов таблицы. Если столбец ссылочной таблицы SIGNED, столбец таблицы ссылок также должен быть SIGNED.
Мое решение, может быть, немного смущает и рассказывает историю о том, почему вы должны иногда смотреть на то, что у вас есть перед вами, а не на эти сообщения:)
Раньше я работал с инженером-форвардом, что не удалось, поэтому это означало, что в моей базе данных уже было несколько таблиц, после чего я сидел, пытаясь исправить ошибки внешних ключей, пытаясь убедиться, что все было идеально, но это побежало против ранее созданных таблиц, поэтому он не должен преобладать.
Я столкнулся с проблемой и смог ее решить, убедившись, что типы данных точно совпадают.
Я использовал SequelPro для добавления ограничения, и он делал первичный ключ как неподписанный по умолчанию.
Я получил ту же ошибку. Причина в моем случае:
Причина заключалась в следующем: поскольку я использовал phpmyadmin для создания некоторых внешних ключей в переименованной базе данных - внешние ключи, созданные с префиксом имени базы данных, но префикс имени базы данных не обновлялся. Таким образом, в резервном-db были ссылки на вновь созданный db.
Имел подобную ошибку, но в моем случае я отсутствовал, чтобы объявить pk как auto_increment.
На всякий случай это может быть полезно любому
У меня была аналогичная ошибка с двумя внешними ключами для разных таблиц, но с одинаковыми именами ключей! Я переименовал ключи, и ошибка исчезла)
У меня была аналогичная ошибка при создании внешнего ключа в таблице Many to Many, где первичный ключ состоял из 2 внешних ключей и другого нормального столбца. Я исправил проблему, исправляя имя таблицы ссылок, т.е. Компанию, как показано в скорректированном коде ниже:
create table company_life_cycle__history -- (M-M)
(
company_life_cycle_id tinyint unsigned not null,
Foreign Key (company_life_cycle_id) references company_life_cycle(id) ON DELETE CASCADE ON UPDATE CASCADE,
company_id MEDIUMINT unsigned not null,
Foreign Key (company_id) references company(id) ON DELETE CASCADE ON UPDATE CASCADE,
activity_on date NOT NULL,
PRIMARY KEY pk_company_life_cycle_history (company_life_cycle_id, company_id,activity_on),
created_on datetime DEFAULT NULL,
updated_on datetime DEFAULT NULL,
created_by varchar(50) DEFAULT NULL,
updated_by varchar(50) DEFAULT NULL
);
У меня была такая же проблема, после чего я исправил имя Engine как Innodb в родительских и дочерних таблицах и исправил имя ссылочного поля
ИНОСТРАННЫЙ КЛЮЧ (c_id
) ССЫЛКИ x9o_parent_table
(c_id
)
то он отлично работает, и таблицы установлены правильно. Это будет полезно для кого-то.