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

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

Я выполнил запрос SHOW CREATE TABLE для обеих таблиц, sourcecodes_tags - это таблица с внешним ключом, sourcecodes - это ссылочная таблица.

CREATE TABLE 'sourcecodes' (
 'id' int(11) unsigned NOT NULL AUTO_INCREMENT,
 'user_id' int(11) unsigned NOT NULL,
 'language_id' int(11) unsigned NOT NULL,
 'category_id' int(11) unsigned NOT NULL,
 'title' varchar(40) CHARACTER SET utf8 NOT NULL,
 'description' text CHARACTER SET utf8 NOT NULL,
 'views' int(11) unsigned NOT NULL,
 'downloads' int(11) unsigned NOT NULL,
 'time_posted' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY ('id'),
 KEY 'user_id' ('user_id'),
 KEY 'language_id' ('language_id'),
 KEY 'category_id' ('category_id'),
 CONSTRAINT 'sourcecodes_ibfk_3' FOREIGN KEY ('language_id') REFERENCES 'languages' ('id') ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT 'sourcecodes_ibfk_1' FOREIGN KEY ('user_id') REFERENCES 'users' ('id') ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT 'sourcecodes_ibfk_2' FOREIGN KEY ('category_id') REFERENCES 'categories' ('id') ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE 'sourcecodes_tags' (
 'sourcecode_id' int(11) unsigned NOT NULL,
 'tag_id' int(11) unsigned NOT NULL,
 KEY 'sourcecode_id' ('sourcecode_id'),
 KEY 'tag_id' ('tag_id'),
 CONSTRAINT 'sourcecodes_tags_ibfk_1' FOREIGN KEY ('tag_id') REFERENCES 'tags' ('id') ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Это код, который генерирует ошибку:

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

Ответ 1

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

Здесь запрос, который может найти эти идентификаторы:

SELECT DISTINCT sourcecode_id FROM 
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id 
WHERE sc.id IS NULL;

Ответ 2

У меня была та же проблема с моей базой данных MySQL, но, наконец, я получил решение, которое сработало для меня.
Так как в моей таблице все было нормально с точки зрения mysql (обе таблицы должны использовать движок InnoDB, и тип данных каждого столбца должен быть одного типа, который принимает участие в ограничении внешнего ключа).
Единственное, что я сделал, - отключил проверку внешнего ключа, а затем включил ее после выполнения операции с внешним ключом.
Шаги, которые я предпринял:

SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0
SET foreign_key_checks = 1;

Ответ 3

Используйте NOT IN, чтобы найти, где ограничения ограничить:

SELECT column FROM table WHERE column NOT IN 
(SELECT intended_foreign_key FROM another_table)

так, точнее:

SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN 
(SELECT id FROM sourcecodes)

EDIT: IN и NOT IN операторы, как известно, намного быстрее, чем операторы JOIN, а также намного проще построить и повторить.

Ответ 4

Усечь таблицы, а затем попытаться добавить ограничение FK.

Я знаю, что это решение немного неудобно, но оно работает на 100%. Но я согласен, что это не идеальное решение для решения проблемы, но я надеюсь, что это поможет.

Ответ 5

Для меня эта проблема была немного другой и супер легко проверить и решить.

Вы должны убедиться, что ОБА из ваших таблиц InnoDB. Если одна из таблиц, а именно справочная таблица, является MyISAM, ограничение не будет выполнено.

    SHOW TABLE STATUS WHERE Name =  't1';

    ALTER TABLE t1 ENGINE=InnoDB;

Ответ 6

Это также происходит при установке внешнего ключа parent.id на child.column, если у child.column уже есть значение 0, а значение parent.id равно 0

Вам нужно убедиться, что каждый child.column имеет значение NULL или имеет значение, существующее в parent.id

И теперь, когда я прочитал выражение nos, написал, что он проверяет.

Ответ 7

У меня была такая же проблема сегодня. Я проверил четыре вещи, некоторые из которых уже упоминались здесь:

  1. Есть ли какие-либо значения в вашем дочернем столбце, которых нет в родительском столбце (кроме NULL, если дочерний столбец имеет значение NULL)?

  2. У дочерних и родительских столбцов одинаковый тип данных?

  3. Есть ли индекс родительского столбца, на который вы ссылаетесь? MySQL, кажется, требует этого по соображениям производительности (http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html)

  4. И этот решил для меня: есть ли в обеих таблицах одинаковые параметры сортировки?

У меня был один стол в UTF-8, а другой в iso-что-то. Это не сработало. После изменения iso-таблицы на сопоставление UTF-8 ограничения могут быть добавлены без проблем. В моем случае phpMyAdmin даже не отображал дочернюю таблицу в iso-кодировке в раскрывающемся списке для создания ограничения внешнего ключа.

Ответ 8

Кажется, что для строки 0 столбца есть недопустимое значение, которое не является допустимым внешним ключом, поэтому MySQL не может установить для него ограничение внешнего ключа.

Вы можете выполнить следующие действия:

  1. Удалите столбец, для которого вы пытались установить ограничение FK.

  2. Добавьте его еще раз и установите его значение по умолчанию как NULL.

  3. Попробуйте снова установить для него ограничение внешнего ключа.

Ответ 9

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

Ответ 10

В итоге я удалю все данные в своей таблице и снова заново сработаю. Оно работает. Не блестящий, но это экономит много времени, особенно ваше приложение все еще находится на стадии разработки без каких-либо данных клиента.

Ответ 11

попробуйте это

SET foreign_key_checks = 0;

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

SET foreign_key_checks = 1;

Ответ 12

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

SELECT * FROM (tablename)
    WHERE (candidate key) <> (proposed foreign key value) 
        AND (candidate key) <> (next proposed foreign key value)

повторите AND (candidate key) <> (next proposed foreign key value) в вашем запросе для каждого значения внешнего ключа.

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

Ответ 13

Очистите данные ваших таблиц и запустите команду. Он будет работать.

Ответ 15

Вам просто нужно ответить на один вопрос:

Ваша таблица уже хранит данные? (Особенно в таблицу включен внешний ключ.)

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

Инструкция удаления: от дочерней (которая включает в себя таблицу внешнего ключа) до родительской таблицы.

Причина, по которой вы не можете добавить внешний ключ после ввода данных, связана с несогласованностью таблицы. Как вы собираетесь работать с новым внешним ключом в прежней таблице, заполненной данными?

Если ответ "нет", следуйте другим инструкциям.

Ответ 16

Я готовил эти решения, и этот пример может помочь.

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

Сначала я вставляю данные строки для ссылочных таблиц (email, credit_card), затем вы получаете идентификатор для каждого, эти идентификаторы необходимы в третьей таблице (клиенте).

Если вы не вставляете сначала строки в ссылочные таблицы, MySQL не сможет сопоставлять, когда вы вставляете новую строку в третью таблицу, ссылающуюся на внешние ключи.

Если вы сначала вставляете ссылочные строки для ссылочных таблиц, тогда строка, которая ссылается на внешние ключи, не возникает ошибка.

Надеюсь, что это поможет.

Ответ 17

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

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

Ответ 18

Вы можете попробовать этот пример

 START TRANSACTION;
 SET foreign_key_checks = 0;
 ALTER TABLE 'job_definers' ADD CONSTRAINT 'job_cities_foreign' FOREIGN KEY 
 ('job_cities') REFERENCES 'drop_down_lists'('id') ON DELETE CASCADE ON UPDATE CASCADE;
 SET foreign_key_checks = 1;
 COMMIT;

Примечание: если вы используете phpmyadmin, просто снимите флажок Включить проверку внешнего ключа

как пример enter image description here

надеюсь, что это решение решить вашу проблему :)

Ответ 19

UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
  SELECT id FROM sourcecodes);

должен помочь избавиться от этих идентификаторов. Или если null не разрешено в sourcecode_id, удалите эти строки или добавьте эти отсутствующие значения в таблицу sourcecodes.

Ответ 20

У меня была та же проблема и найдено решение, поместив NULL вместо NOT NULL в столбец внешнего ключа. Вот запрос:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

MySQL выполнил этот запрос!

Ответ 21

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

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