Невозможно добавить ограничение внешнего ключа, верстак

Я использовал верстак для реализации схемы базы данных, но я получаю эту ошибку при использовании внешних ключей в определенной таблице.

1215 - Невозможно добавить ограничение внешнего ключа

SQL-запрос:

CREATE TABLE IF NOT EXISTS `Gam3ty`.`Frequently_Used_Location` (
`idFrequently_Used_Location` INT NOT NULL,
`User_idUser` INT NOT NULL,
`User_College_idCollege` INT NOT NULL,
PRIMARY KEY (`idFrequently_Used_Location`,`User_idUser`,`User_College_idCollege`),
INDEX `fk_Frequently_Used_Location_User1_idx` (`User_idUser` ASC,`User_College_idCollege` ASC),
CONSTRAINT `fk_Frequently_Used_Location_User1`
FOREIGN KEY (`User_idUser` , `User_College_idCollege`)
REFERENCES `Gam3ty`.`User` (`idUser` , `College_idCollege`)

мой SQL:

CREATE SCHEMA IF NOT EXISTS `Gam3ty` DEFAULT CHARACTER SET utf8 ;
USE `Gam3ty` ;

-- -----------------------------------------------------
-- Table `Gam3ty`.`Frequently_Used_Location`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Gam3ty`.`Frequently_Used_Location` (
`idFrequently_Used_Location` INT NOT NULL,
`User_idUser` INT NOT NULL,
`User_College_idCollege` INT NOT NULL,
PRIMARY KEY (`idFrequently_Used_Location`, `User_idUser`,          `User_College_idCollege`),
INDEX `fk_Frequently_Used_Location_User1_idx` (`User_idUser` ASC, `User_College_idCollege` ASC),
CONSTRAINT `fk_Frequently_Used_Location_User1`
FOREIGN KEY (`User_idUser` , `User_College_idCollege`)
REFERENCES `Gam3ty`.`User` (`idUser` , `College_idCollege`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `Gam3ty`.`Location`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Gam3ty`.`Location` (
`idLocation` INT NOT NULL,
`Frequently_Used_Location_idFrequently_Used_Location` INT NOT NULL,
`Frequently_Used_Location_User_idUser` INT NOT NULL,
`Frequently_Used_Location_User_College_idCollege` INT NOT NULL,
`type` VARCHAR(45) NULL,
PRIMARY KEY (`idLocation`),
INDEX `fk_Location_Frequently_Used_Location1_idx`  (`Frequently_Used_Location_idFrequently_Used_Location` ASC,    `Frequently_Used_Location_User_idUser` ASC, `Frequently_Used_Location_User_College_idCollege` ASC),
CONSTRAINT `fk_Location_Frequently_Used_Location1`
FOREIGN KEY (`Frequently_Used_Location_idFrequently_Used_Location` ,  `Frequently_Used_Location_User_idUser` ,        `Frequently_Used_Location_User_College_idCollege`)
 REFERENCES `Gam3ty`.`Frequently_Used_Location`         (`idFrequently_Used_Location`,  `User_idUser` , `User_College_idCollege`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `Gam3ty`.`University`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Gam3ty`.`University` (
`idUniversity` INT NOT NULL,
`Location_idLocation` INT NOT NULL,
`Info` VARCHAR(45) NULL,
PRIMARY KEY (`idUniversity`, `Location_idLocation`),
INDEX `fk_University_Location1_idx` (`Location_idLocation` ASC),
CONSTRAINT `fk_University_Location1`
FOREIGN KEY (`Location_idLocation`)
REFERENCES `Gam3ty`.`Location` (`idLocation`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `Gam3ty`.`College`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Gam3ty`.`College` (
`idCollege` INT NOT NULL,
`University_idUniversity` INT NOT NULL,
`Location_idLocation` INT NOT NULL,
`Info` VARCHAR(45) NULL,
`Staff` VARCHAR(45) NULL,
`Department` VARCHAR(45) NULL,
PRIMARY KEY (`idCollege`, `University_idUniversity`, `Location_idLocation`),
INDEX `fk_College_University1_idx` (`University_idUniversity` ASC),
INDEX `fk_College_Location1_idx` (`Location_idLocation` ASC),
CONSTRAINT `fk_College_University1`
FOREIGN KEY (`University_idUniversity`)
REFERENCES `Gam3ty`.`University` (`idUniversity`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_College_Location1`
FOREIGN KEY (`Location_idLocation`)
REFERENCES `Gam3ty`.`Location` (`idLocation`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `Gam3ty`.`User`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Gam3ty`.`User` (

`idUser` INT NOT NULL,
`College_idCollege` INT NOT NULL,
`UserName` VARCHAR(45) NOT NULL,
`Password` VARCHAR(45) NOT NULL,
`E-mail` VARCHAR(45) NOT NULL,
`Social_media_accounts` VARCHAR(45) NULL,
`Gender` VARCHAR(45) NOT NULL,
`Job` VARCHAR(45) NOT NULL,
`Tel-num` BIGINT(11) NULL,
`Adress` VARCHAR(45) NULL,
PRIMARY KEY (`idUser`, `College_idCollege`, `UserName`),
INDEX `fk_User_College_idx` (`College_idCollege` ASC),
CONSTRAINT `fk_User_College`
FOREIGN KEY (`College_idCollege`)
REFERENCES `Gam3ty`.`College` (`idCollege`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

Я проверил типы данных, и они все одинаковые, также каждый внешний ключ является первичным ключом в своей исходной таблице.

2 ответа

Решение

Таблицы создаются по порядку сверху вниз при запуске сценария SQL.

Вы не можете создать внешний ключ, который ссылается на таблицу, которая еще не была создана.

Вы должны упорядочить таблицы так, чтобы каждая таблица создавалась перед любыми таблицами, которые на нее ссылаются.


@Rahul написал:

Вам нужно сослаться на все столбцы, обозначенные как первичный ключ.

Я согласен, что это рекомендуемая практика, потому что в противном случае вы можете создать внешний ключ, где данная строка ссылается на несколько строк в родительской таблице. Это приводит к неоднозначной семантике. Например, можете ли вы удалить строку в родительской таблице, если есть строка, ссылающаяся на нее в дочерней таблице, но есть вторая строка в родительской таблице, которая удовлетворяет ссылке? Это нарушает определение ссылочной целостности в стандартном SQL.

Тем не менее InnoDB это позволяет. Вы можете создать внешний ключ, который ссылается на любое самое левое подмножество столбцов любого ключа (уникального или неуникального). Это очень плохая идея, но InnoDB позволяет вам это сделать и не выдает ошибку.

Следующее безумие, но это не ошибка для InnoDB:

create table foo (a int, b int, key (a, b));
create table bar (a int, foreign key (a) references foo(a));

Это причина таблицы Gam3ty.User определяет первичный ключ в 3 столбцах, как показано ниже, но вы ссылаетесь только на два из них. который создает частичную функциональную зависимость. Вы должны ссылаться на все столбцы, обозначенные как первичный ключ

CREATE TABLE IF NOT EXISTS `Gam3ty`.`User` (
....
PRIMARY KEY (`idUser`, `College_idCollege`, `UserName`)

Ваша справочная таблица

FOREIGN KEY (`User_idUser` , `User_College_idCollege`)
REFERENCES `Gam3ty`.`User` (`idUser` , `College_idCollege`)
Другие вопросы по тегам