it-roy-ru.com

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

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

Executing SQL script in server

ERROR: Error 1215: Cannot add foreign key constraint

-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
  `Clients_Case_Number` INT NOT NULL ,
  `Staff_Emp_ID` INT NOT NULL ,
  PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
  INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
  INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
  CONSTRAINT `fk_Clients_has_Staff_Clients`
    FOREIGN KEY (`Clients_Case_Number` )
    REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Clients_has_Staff_Staff1`
    FOREIGN KEY (`Staff_Emp_ID` )
    REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

Выполнение SQL-скрипта завершено: операторы: 7 успешно выполнены, 1 не удалось

Вот SQL для родительских таблиц.

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
  `Case_Number` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  `Address` CHAR(50) NULL ,
  `Phone_Number` INT(10) NULL ,
  PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB

CREATE  TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
  `Emp_ID` INT NOT NULL ,
  `First_Name` CHAR(10) NULL ,
  `Middle_Name` CHAR(10) NULL ,
  `Last_Name` CHAR(10) NULL ,
  PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB
275
Robert B

Я предполагаю, что Clients.Case_Number и/или Staff.Emp_ID не совпадают с типом данных, как Clients_has_Staff.Clients_Case_Number и Clients_has_Staff.Staff_Emp_ID.

Возможно, столбцы в родительских таблицах являются INT UNSIGNED?

Они должны быть точно одинакового типа данных в обеих таблицах.

496
Ike Walker

Причины, по которым вы можете получить ошибку ограничения внешнего ключа:

  1. Вы не используете InnoDB в качестве движка для всех таблиц.
  2. Вы пытаетесь сослаться на несуществующий ключ в целевой таблице. Убедитесь, что это ключ в другой таблице (это может быть первичный или уникальный ключ)
  3. Типы столбцов не одинаковы (за исключением того, что столбец в ссылочной таблице может иметь значение NULL).
  4. Если PK/FK является varchar, убедитесь, что сопоставление одинаково для обоих.

Обновление:

  1. Одной из причин может быть также то, что столбец, который вы используете для ON DELETE SET NULL, не определен как нулевой. Поэтому убедитесь, что для столбца установлено значение по умолчанию null.

Проверьте это.

199
Explosion Pills

Для других такая же ошибка не всегда может быть связана с несоответствием типа столбца, вы можете узнать больше информации об ошибке ключа mysql foriegn, введя команду

SHOW ENGINE INNODB STATUS;

вы можете найти ошибку в верхней части напечатанного сообщения, например

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

74
arvind

Ошибка 1215 раздражает. Ответ таблетки взрыва охватывает основы. Вы хотите, чтобы начать с этого. Тем не менее, есть и другие, более тонкие случаи, на которые стоит обратить внимание:

Например, когда вы пытаетесь связать ПЕРВИЧНЫЕ КЛЮЧИ разных таблиц, убедитесь, что вы указали правильные параметры ON UPDATE и ON DELETE. Например.:

...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....

не будет летать, потому что ПЕРВИЧНЫЕ КЛЮЧИ (такие как id) не могут быть NULL.

Я уверен, что при добавлении такого рода ограничений возникают еще более тонкие проблемы, поэтому при обнаружении ошибок ограничений всегда следите за тем, чтобы ограничения и их последствия имели смысл в текущем контексте. Удачи с вашей ошибкой 1215!

12
Domi

Проверьте параметры сортировки таблиц, используя SHOW TABLE STATUS вы можете проверить информацию о таблицах, включая параметры сортировки.

Обе таблицы должны иметь одинаковое сопоставление.

Это случилось со мной. 

7
Carlos Laspina

В моем случае я удалил таблицу с помощью SET FOREIGN_KEY_CHECKS=0, затем SET FOREIGN_KEY_CHECKS=1 после. Когда я пошел, чтобы перезагрузить таблицу, я получил error 1215. Проблема заключалась в том, что в базе данных была другая таблица с внешним ключом к таблице, которую я удалил и перезагружала. Часть процесса перезагрузки включала изменение типа данных для одного из полей, что делало внешний ключ из другой таблицы недействительным, вызывая, таким образом, error 1215. Я решил проблему, отбросив, а затем перезагрузив другую таблицу с новым типом данных для соответствующего поля.

7
CodeMed

Я столкнулся с ловушкой «Ошибка 1215: невозможно добавить ограничение внешнего ключа» при использовании Laravel 4, особенно с генераторами JeffreyWay Laravel 4.

В Laravel 4 вы можете использовать Генераторы JeffreyWay для генерации файлов миграции для создания таблиц один за другим, что означает, что каждый файл миграции генерирует одну таблицу .. Вы должны знать, что каждый файл миграции генерируется с временная метка в имени файла, которая дает файлам порядок. Порядок генерации также является порядком операции миграции, когда вы запускаете команду CLI Artisan "php artisan migrate" . Таким образом, если файл запрашивает ограничение внешнего ключа, ссылающееся на ключ, который будет, но еще не, генерируется в последнем файле, ошибка 1215 запускается . В этом случае вам нужно настроить порядок генерации файлов миграции. Создайте новые файлы в правильном порядке, скопируйте содержимое, затем удалите неупорядоченные старые файлы.

5
user2975399

Я получил ту же ошибку при попытке добавить FK. В моем случае проблема была вызвана PK таблицы FK, который был помечен как неподписанный.

4
Alex

У меня такая же проблема.
Я решил это следующим образом:

Я создал следующую строку в
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)

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

Удачи!

Фелипе Терсио

3
user3478348

Другая причина: если вы используете ON DELETE SET NULLall столбцы, которые используются во внешнем ключе, должны разрешать нулевые значения. Кто-то еще узнал об этом в этот вопрос

Насколько я понимаю, это не будет проблемой в отношении целостности данных, но кажется, что MySQL просто не поддерживает эту функцию (в 5.7).

2
robsch

Проверьте совместимость таблицы. Например, если одна таблица MyISAM, а другая InnoDB, у вас может быть эта проблема.

2
Dennis

Для MySQL (INNODB) ... получить определения для столбцов, которые вы хотите связать

SELECT * FROM information_schema.columns WHERE 
TABLE_NAME IN (tb_name','referenced_table_name') AND 
COLUMN_NAME  IN ('col_name','referenced_col_name')\G

сравнить и проверить оба определения столбцов 

то же самое COLUMN_TYPE (длина), то же самое COLATION 

может быть полезно играть как

set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
2
bortunac

Я не могу найти эту ошибку

CREATE TABLE RATING (

Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE, 

PRIMARY KEY (Riv_Id, Mov_Id),

FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,

FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
2
gathila

Это также происходит, когда тип столбцов не совпадает.

например если столбец, на который вы ссылаетесь, равен UNSIGNED INT, а столбец, к которому вы обращаетесь, - INT, то вы получите эту ошибку.

2
Mozaffar

у меня была та же проблема, мое решение:

До:

CREATE TABLE EMPRES
( NoFilm smallint NOT NULL

  PRIMARY KEY (NoFilm)

  FOREIGN KEY (NoFilm) REFERENCES cassettes

);

Решение:

CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,

 PRIMARY KEY (NoFilm)

);

Я надеюсь, что это поможет;)

2
Yacine Richthofen

Я испытал эту ошибку по совершенно другой причине. Я использовал MySQL Workbench 6.3 для создания моей модели данных (потрясающий инструмент). Я заметил, что когда порядок столбцов, определенный в определении ограничения внешнего ключа, не соответствует последовательности столбцов таблицы, эта ошибка также генерируется.

Мне потребовалось около 4 часов, чтобы попробовать все остальное, кроме проверки этого.

Теперь все работает хорошо, и я могу вернуться к кодированию. :-)

1
Stephen Nortje

Wooo, я только что получил это! Это была смесь множества уже опубликованных ответов (innoDB, unsigned и т.д.). Однако здесь я не увидел одну вещь: если ваш FK указывает на PK, убедитесь, что в исходном столбце есть значение, которое имеет смысл. Например, если PK является mediumint (8), убедитесь, что в исходном столбце также есть mediumint (8). Это было частью проблемы для меня.

1
Chris Neve

Для меня это были типы столбцов. BigINT! = INT. 

Но тогда это все еще не работало. 

Поэтому я проверил двигатели. Убедитесь, что Table1 = InnoDB и Table = InnoDB

1
Chad

Когда эта ошибка возникает из-за того, что ссылочная таблица использует механизм MyISAM, этот ответ обеспечивает быстрый способ преобразования вашей базы данных, поэтому все таблицы моделей Django используют InnoDB: https://stackoverflow.com/a/15389961/2950621

Это команда управления Django, которая называется convert_to_innodb.

1
nmgeek

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

Short Answer: Набор символов и сопоставление схемы, таблицы, столбца, таблицы ссылок, столбца ссылок и любых других таблиц, которые ссылаются на родительскую таблицу, должны совпадать. 

Длинный ответ: У меня в таблице был тип данных ENUM. Я изменил это на VARCHAR, и я могу получить значения из справочной таблицы, чтобы мне не пришлось изменять родительскую таблицу, чтобы добавить дополнительные параметры. Эти отношения с внешним ключом казались простыми, но я получил ошибку 1215. arvind ответ и следующая ссылка предложили использовать 

SHOW ENGINE INNODB STATUS;

При использовании этой команды я получил следующее подробное описание ошибки без дополнительной полезной информации

Не удается найти индекс в ссылочной таблице, где указанные столбцы отображаются как первые столбцы или типы столбцов в таблице и ссылочной таблице не соответствуют ограничениям. Обратите внимание, что тип внутренней памяти ENUM и SET изменился в таблицы, созданные с помощью> = InnoDB-4.1.12, и такие столбцы в старых таблицах на такие столбцы нельзя ссылаться в новых таблицах. Пожалуйста, обратитесь к http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html для правильного определения внешнего ключа.

После чего я использовал SET FOREIGN_KEY_CHECKS=0;, как это было предложено Арвинд Бхарадвадж и ссылку здесь :

Это дало следующее сообщение об ошибке:

Код ошибки: 1822. Не удалось добавить ограничение внешнего ключа. Отсутствует индекс для ограничения

На этом этапе я «перепроектировал» схему и смог установить связь между внешним ключом и диаграммой EER. На форвард инженера я получил следующую ошибку:

Ошибка 1452: Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа терпит неудачу

Когда я «перевел инженера» и перевел диаграмму EER в новую схему, сценарий SQL запустился без проблем. Сравнивая сгенерированный SQL из попыток направить инженера, я обнаружил, что разница заключается в наборе символов и сопоставлении. Родительская таблица, дочерняя таблица и два столбца имели набор символов utf8mb4 и параметры сортировки utf8mb4_0900_ai_ci, однако другой столбец в родительской таблице был связан с использованием CHARACTER SET = utf8 , COLLATE = utf8_bin ; для другой дочерней таблицы.

Для всей схемы я изменил набор символов и параметры сортировки для всех таблиц и всех столбцов следующим образом:

CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;

Это наконец решило мою проблему с ошибкой 1215.

Side Примечание: Параметры сортировки utf8mb4_general_ci работают в MySQL Workbench 5.0 или более поздней версии. Collation utf8mb4_0900_ai_ci работает только для MySQL Workbench 8.0 или выше. Я считаю, что одна из причин, по которой у меня возникли проблемы с набором символов и сопоставлением, связана с обновлением MySQL Workbench до 8.0 между ними. Вот ссылка , которая больше говорит об этом сопоставлении.

1
CoderBapu

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

SET FOREIGN_KEY_CHECKS=0;

0
Arvind Bhardwaj

Это тонкая версия того, что уже было сказано, но в моем случае у меня было 2 базы данных (foo и bar). Сначала я создал foo и не понял, что он ссылается на внешний ключ в bar.baz (который еще не был создан). Когда я пытался создать bar.baz (без каких-либо внешних ключей), я продолжал получать эту ошибку. Посмотрев некоторое время, я нашел внешний ключ в foo.

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

0
ajon

Знайте об использовании обратных цитат тоже. У меня было в скрипте следующее утверждение

ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;

но обратные кавычки в конце были ложными. Это должно было быть:

ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);

MySQL, к сожалению, не дает подробностей об этой ошибке ...

0
Olivier Faucheux

при попытке сделать внешний ключ при использовании миграции laravel

как этот пример:

таблица пользователей

    public function up()
{
    Schema::create('flights', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->TinyInteger('color_id')->unsigned();
        $table->foreign('color_id')->references('id')->on('colors');
        $table->timestamps();
    });
}

таблица цветов

    public function up()
{
    Schema::create('flights', function (Blueprint $table) {
        $table->increments('id');
        $table->string('color');
        $table->timestamps();
    });
}

иногда свойства не работают 

[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

эта ошибка произошла из-за того, что внешний ключ (тип) в [таблица пользователей] отличается от первичного ключа (тип) в [таблица цветов]

Для решения этой проблемы следует изменить первичный ключ в [таблица цветов] 

$table->tinyIncrements('id');


Когда вы используете первичный ключ $table->Increments('id');

вы должны использовать Integer в качестве внешнего ключа

    $table-> unsignedInteger('fk_id');
    $table->foreign('fk_id')->references('id')->on('table_name');

Когда вы используете первичный ключ $table->tinyIncrements('id');

вы должны использовать unsignedTinyInteger в качестве внешнего ключа

    $table-> unsignedTinyInteger('fk_id');
    $table->foreign('fk_id')->references('id')->on('table_name');

Когда вы используете первичный ключ $table->smallIncrements('id');

вы должны использовать unsignedSmallInteger в качестве внешнего ключа

    $table-> unsignedSmallInteger('fk_id');
    $table->foreign('fk_id')->references('id')->on('table_name');

Когда вы используете первичный ключ $table->mediumIncrements('id');

вы должны использовать unsignedMediumInteger в качестве внешнего ключа

    $table-> unsignedMediumInteger('fk_id');
    $table->foreign('fk_id')->references('id')->on('table_name');
0
MAHDI ABDULSAHIB

Я знаю, что я ОЧЕНЬ опоздал на вечеринку, но я хочу выложить это здесь, чтобы это было в списке.

Так же как и все вышеприведенные советы, чтобы убедиться, что поля определены одинаково, а типы таблиц также имеют одинаковое сопоставление, убедитесь, что вы не допустили ошибку новичка, пытаясь связать поля, где данные в поле CHILD не совпадают. уже в поле РОДИТЕЛЯ. Если у вас есть данные, которые находятся в поле CHILD, которые вы еще не ввели в поле PARENT, то это вызовет эту ошибку. Обидно, что сообщение об ошибке не более полезно.

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

Удачи.

0
noowie

Для меня ошибка 1215 произошла, когда я импортировал файл дампа, созданный mysqldump, который создает таблицы в алфавитном порядке, что в моем случае вызывало внешние ключи для ссылочных таблиц, созданных позже в файле. (Перейдите на эту страницу, чтобы указать на нее: https://www.percona.com/blog/2017/04/06/dealing-mysql-error-code-1215-cannot-add-foreign-key-constraint/ )

Поскольку mysqldump упорядочивает таблицы в алфавитном порядке, и я не хотел менять имена таблиц, я следовал инструкциям в ответе JeremyWeir на этой странице , в котором говорится, что set FOREIGN_KEY_CHECKS = 0; должен находиться в верхней части файла дампа, а SET FOREIGN_KEY_CHECKS = 1; - в нижняя часть файла дампа.

Это решение сработало для меня.

0
Arya

Другим источником этой ошибки является то, что у вас есть 2 или более одинаковых имен таблиц с одинаковыми именами внешних ключей. Это иногда случается с людьми, которые используют программное обеспечение для моделирования и проектирования, такое как Mysql Workbench, и позже генерируют сценарий из проекта. 

0
Dima Dz