MySQL이 외래 키 제약 조건을 추가 할 수 없음
따라서 프로젝트 요구 사항으로 데이터베이스에 외래 키 제약 조건을 추가하려고하는데 다른 테이블에서 처음 또는 두 번 작동했지만 외래 키 제약 조건을 추가하려고 할 때 오류가 발생하는 두 개의 테이블이 있습니다. 내가 얻는 오류 메시지는 다음과 같습니다.
오류 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
.
또한 set foreign_key_checks=0
DDL을 실행하기 전에 조회 를 실행하여 관련 하위 테이블 전에 모든 상위 테이블을 작성하지 않고 임의의 순서로 테이블을 작성할 수 있습니다.
한 필드를 "서명되지 않음"으로 설정하고 다른 필드는 설정하지 않았습니다. 두 열을 모두 서명되지 않음으로 설정하면 제대로 작동합니다.
- 엔진 은 동일해야합니다. 예 : InnoDB
- 데이터 유형 은 동일하고 길이가 같아야합니다. 예 : VARCHAR (20)
- 데이터 정렬 열 문자 집합이 동일해야합니다. 예 : utf8
감시 : 테이블의 데이터 정렬이 동일하더라도 열의 열이 여전히 다를 수 있습니다. - 고유 -외래 키는 참조 테이블에서 고유 한 필드 (일반적으로 기본 키) 를 참조해야합니다.
동일한 유형의 기본 키 -int (11) -외래 키 -smallint (5) -를 사용하십시오.
그것이 도움이되기를 바랍니다!
두 테이블의 문자 인코딩 및 데이터 정렬이 동일한 지 확인하십시오.
내 경우에는 테이블 중 하나가 사용 중이고 utf8
다른 하나는을 사용 중이었습니다 latin1
.
인코딩이 동일하지만 데이터 정렬이 다른 또 다른 경우가 있습니다. utf8_general_ci
다른 하나utf8_unicode_ci
이 명령을 실행하여 테이블의 인코딩 및 데이터 정렬을 설정할 수 있습니다.
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
나는 이것이 누군가를 돕기를 바랍니다.
표 B에서 FOREIGN KEY를 설정하려면 표 A에서 KEY를 설정해야합니다.
표 A : INDEX id
( id
)
그리고 표 B에서
CONSTRAINT `FK_id` FOREIGN KEY (`id`) REFERENCES `table-A` (`id`)
나는 같은 문제가 있었고 해결책은 매우 간단했습니다. 솔루션 : 테이블에 선언 된 외래 키가 null이 아니어야합니다.
참조 : SET NULL 조치를 지정하는 경우 하위 테이블의 열을 NOT NULL로 선언하지 않았는지 확인하십시오. ( REF )
두 테이블이 모두 InnoDB 형식인지 확인하십시오. 하나가 MyISAM 형식이더라도 외래 키 제약 조건이 작동하지 않습니다.
또한 두 가지 필드의 유형이 동일해야합니다. 하나가 INT이면 다른 하나도 INT 여야합니다. 하나가 VARCHAR이면 다른 하나도 VARCHAR이어야합니다.
다음 규칙을 확인하십시오.
먼저 이름이 테이블 이름에 올바른지 확인합니다.
두 번째 올바른 데이터 유형은 외래 키에 제공됩니까?
나는 문제에 직면하고 데이터 형식이 정확히 일치하는지 확인하여 문제를 해결할 수있었습니다.
제약 조건을 추가하기 위해 SequelPro를 사용하고 있었고 기본적으로 기본 키를 서명되지 않은 상태로 만들었습니다.
두 테이블 열의 서명을 확인하십시오. 참조 테이블 열이 SIGNED이면 참조 테이블 열도 SIGNED 여야합니다.
기본 키가 2 개의 외래 키와 다른 일반 열로 구성된 Many to Many 테이블에서 외래 키를 만들 때 비슷한 오류가 발생했습니다. 아래의 수정 된 코드에 표시된 것처럼 참조 된 테이블 이름 즉 회사를 수정하여 문제를 해결했습니다.
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
);
다른 테이블에 대해 두 개의 외래 키가 있지만 키 이름이 동일한 비슷한 오류가 발생했습니다! 키 이름을 변경했으며 오류가 발생했습니다)
비슷한 오류가 있었지만 제 경우에는 pk를 auto_increment로 선언하지 못했습니다.
누군가에게 도움이 될 수 있도록
같은 오류가 발생했습니다. 내 경우의 원인은 다음과 같습니다.
- 전체 데이터베이스를 복사하여 phpmyadmin을 통해 데이터베이스 백업을 만들었습니다.
- 이전 db가 선택하고 동일한 이름으로 새 db를 작성했습니다.
- 업데이트 된 테이블과 데이터를 만들기 위해 SQL 스크립트를 시작했습니다.
- 오류가 발생했습니다. 또한 foreign_key_checks를 비활성화했을 때. 데이터베이스가 완전히 비었습니다.
그 이유는 다음과 같습니다. phpmyadmin을 사용하여 이름이 바뀐 데이터베이스에 외래 키를 만들었으므로 데이터베이스 이름 접두사로 만들었지 만 데이터베이스 이름 접두사로 작성된 외래 키는 업데이트되지 않았습니다. 따라서 backup-db에 새로 작성된 db를 가리키는 참조가 여전히있었습니다.
내 해결책은 약간 당황스럽고 왜 때때로이 게시물 대신 당신 앞에있는 것을보아야하는지에 대한 이야기를 들려줍니다. :)
나는 이전에 엔지니어를 고용했는데 실패했다. 그래서 내 데이터베이스에는 이미 몇 개의 테이블이 있었으므로 모든 것이 완벽하다는 것을 확인하려고 외래 키 제약 실패를 해결하려고 노력했지만 이전에 작성된 테이블이므로 우선하지 않았습니다.
이 오류의 또 다른 원인은 테이블 또는 열에 예약 키워드가 포함 된 경우입니다 .
때때로 사람들은 이것을 잊어 버립니다.
필자의 경우 쿼리를 실행할 때 MySQL 콘솔에서 명시 적으로 알리지 않은 구문 오류가 발생했습니다. 그러나 SHOW ENGINE INNODB STATUS
사령부 LATEST FOREIGN KEY ERROR
에서는
Syntax error close to:
REFERENCES`role`(`id`) ON DELETE CASCADE) ENGINE = InnoDB DEFAULT CHARSET = utf8
나는 사이의 공백을 떠나야했습니다 REFERENCES
과 role
그것이 작동되도록 할 수 있습니다.
참고 : 다음 표는 데이터베이스에서 일부 R & D를 수행 할 때 일부 사이트에서 가져온 것입니다. 따라서 명명 규칙이 올바르지 않습니다.
나에게 문제는 부모 테이블에 내가 만든 것과 다른 문자 세트가 있다는 것입니다.
부모 테이블 (PRODUCTS)
products | CREATE TABLE `products` (
`productCode` varchar(15) NOT NULL,
`productName` varchar(70) NOT NULL,
`productLine` varchar(50) NOT NULL,
`productScale` varchar(10) NOT NULL,
`productVendor` varchar(50) NOT NULL,
`productDescription` text NOT NULL,
`quantityInStock` smallint(6) NOT NULL,
`buyPrice` decimal(10,2) NOT NULL,
`msrp` decimal(10,2) NOT NULL,
PRIMARY KEY (`productCode`),
KEY `productLine` (`productLine`),
CONSTRAINT `products_ibfk_1` FOREIGN KEY (`productLine`) REFERENCES `productlines` (`productLine`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
문제가있는 Child Table (PRICE_LOGS)
price_logs | CREATE TABLE `price_logs` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`productCode` varchar(15) DEFAULT NULL,
`old_price` decimal(20,2) NOT NULL,
`new_price` decimal(20,2) NOT NULL,
`added_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `productCode` (`productCode`),
CONSTRAINT `price_logs_ibfk_1` FOREIGN KEY (`productCode`) REFERENCES `products` (`productCode`) ON DELETE CASCADE ON UPDATE CASCADE
);
수정
price_logs | CREATE TABLE `price_logs` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`productCode` varchar(15) DEFAULT NULL,
`old_price` decimal(20,2) NOT NULL,
`new_price` decimal(20,2) NOT NULL,
`added_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `productCode` (`productCode`),
CONSTRAINT `price_logs_ibfk_1` FOREIGN KEY (`productCode`) REFERENCES `products` (`productCode`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
내 문제는 다른 테이블보다 먼저 관계 테이블을 만들려고한다는 것입니다!
나는이 같은 문제가 있었고 부모와 자식 테이블 모두에서 엔진 이름을 Innodb로 수정하고 참조 필드 이름 FOREIGN KEY ( c_id
) REFERENCES x9o_parent_table
( c_id
)를 수정
한 다음 제대로 작동하고 테이블이 올바르게 설치되었습니다. 이것은 누군가를 위해 가득 차게 사용될 것입니다.
참고 : https://stackoverflow.com/questions/15534977/mysql-cannot-add-foreign-key-constraint
'Programing' 카테고리의 다른 글
AngularJs : 파일 입력 필드의 변경 사항을 확인하는 방법은 무엇입니까? (0) | 2020.03.25 |
---|---|
JavaScript를 사용하여 전체 경로에서 파일 이름을 얻는 방법은 무엇입니까? (0) | 2020.03.25 |
"x = x ++"다음에 x는 무엇입니까? (0) | 2020.03.25 |
Doctrine2 : 참조 테이블에 추가 열이있는 다대 다를 처리하는 가장 좋은 방법 (0) | 2020.03.25 |
대수 데이터 유형의 대수를 남용-왜 이것이 작동합니까? (0) | 2020.03.25 |