Не могу связать две таблицы - ошибка “Cannot add foreign key constraint”

176
22 января 2019, 23:10

В первой таблице стараюсь связать две другие по id, но получаю ошибку:

Cannot add foreign key constraint

Из-за чего возникает данная ошибка ?

CREATE TABLE IF NOT EXISTS `gregs_list`.`Book_Author` (
  `id` INT NOT NULL,
  `book-id` INT NOT NULL,
  `author-id` INT NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB CHARACTER SET utf8;
CREATE TABLE IF NOT EXISTS `gregs_list`.`Books` (
  `id` INT not NULL,
  `name` VARCHAR(200) NOT NULL,
  `published` DATE NULL,
  `genre` VARCHAR(45) NULL,
  `rating` INT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  CONSTRAINT `kniga`
    FOREIGN KEY (`id`)
    REFERENCES `gregs_list`.`Book_Author` (`book-id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `gregs_list`.`Authors` (
  `id` INT NOT NULL,
  `name` VARCHAR(45) NULL,
  `gender` VARCHAR(45) NULL,
  `born` DATE NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  CONSTRAINT `id`
    FOREIGN KEY (`id`)
    REFERENCES `gregs_list`.`Book_Author` (`author-id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB CHARACTER SET utf8;
Answer 1

У вас отсутствуют индексы полей book-id и author-id. Измените первый запрос, добавив в него создание индексов:

CREATE TABLE IF NOT EXISTS `gregs_list`.`Book_Author` (
  `id` INT NOT NULL,
  `book-id` INT NOT NULL,
  `author-id` INT NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  INDEX `book-id` (`book-id`),
  INDEX `author-id` (`author-id`))
ENGINE = InnoDB CHARACTER SET utf8;
Answer 2

К сожалению, текст ошибки связанный с созданием foreign key в mysql довольно бесполезен. (может быть в 8.0 ситуацию улучшили, не проверял)

Точное описание ошибки возможно найти в несколько неожиданном месте - необходимо запросить статус storage engine:

show engine innodb status;

Затем в полученном тексте найти раздел LATEST FOREIGN KEY ERROR, где будет нормальное описание ошибки и некоторые пояснения. В этом случае примерно вот такое сообщение (это с моего тестового mysql 5.5)

LATEST FOREIGN KEY ERROR

181001 10:16:25 Error in foreign key constraint of table gregs_list/Books:

FOREIGN KEY (`id`)
REFERENCES `gregs_list`.`Book_Author` (`book-id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION) ENGINE = InnoDB: 

Cannot find an index in the referenced table where the referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint. Note that the internal storage type of ENUM and SET changed in tables created with >= InnoDB-4.1.12, and such columns in old tables cannot be referenced by such columns in new tables. See http://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html for correct foreign key definition.

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

Answer 3

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

P.S. Почитайте на тему индексов в целом. Конструкции вида

PRIMARY KEY (id), UNIQUE INDEX id_UNIQUE (id ASC)

некорректны.

READ ALSO
Как расположить блоки в колонну при масштабировании?

Как расположить блоки в колонну при масштабировании?

Учусь верстать адаптивные сайтыНа макете есть блок с 3 div по горизонтали

174
Позиционирование тeкстa

Позиционирование тeкстa

Как сделать текст как под цифрой 1 средствами HTML/CSS/PHP?

176
Как убрать отступ от верхнего края браузера?

Как убрать отступ от верхнего края браузера?

У меня не получается убрать отступ от верхнего края страницы :

135
SVG / SMIL Последователый вызов двух анимаций

SVG / SMIL Последователый вызов двух анимаций

Подскажите, как при работе со SMIL анимацией в SVG добиться эффекта последовательного выполнения двух анимаций

166