Добавить внешний ключ в существующую таблицу


324

Я хочу добавить внешний ключ в таблицу под названием "katalog".

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Когда я пытаюсь сделать это, я получаю это сообщение об ошибке:

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

Ошибка в состоянии INNODB:

120405 14:02:57 Ошибка ограничения внешнего ключа таблицы mytable. # Sql-7fb1_7d3a:

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

Когда я использую этот запрос, он работает, но с неправильным действием «при удалении»:

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

Обе таблицы InnoDB, и оба поля "INT (11) не нуль". Я использую MySQL 5.1.61. Попытка запустить этот запрос ALTER с помощью MySQL Workbench (новейшей версии) на MacBook Pro.

Таблица создания операторов:

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

1
Поскольку вы не опубликовали вывод SHOW CREATE TABLE, я могу только спросить - действительно ли имя столбца идентифицировано в верхнем регистре?
NB

Ну, теперь легче определить - katalogесть int(11) unsigned. spracheне имеет usignedчасти, поэтому два столбца не совпадают.
NB

Вы имеете в виду, что оба первичных поля должны быть одного типа данных?
frgtv10

2
Это проблема с вашим дизайном: во-первых, вы ссылаетесь на два auto_incrementстолбца, что плохо. Кроме того , руководство по MySQL говорит: Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.. Поэтому да, похожий тип данных и тот же знак.
NB

2
Я не ссылаюсь на два поля auto_increment. katalog.Sprache (не авто) -> sprache.ID (авто)
frgtv10

Ответы:


560

Чтобы добавить внешний ключ (grade_id) в существующую таблицу (пользователи), выполните следующие действия:

ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

12
Причины помогают мне понять и запомнить. Это потому, что вы не можете добавить внешний ключ в поле без знака, правильно?
PixMach

8
@PixMach, ответ - нет. Вы можете иметь целые числа со знаком в качестве внешних ключей. Как отмечено в вопросе NB, тип и знак полей должны совпадать. Таким образом, если ваш первичный ключ в таблице поиска - UNSIGNED, то поле внешнего ключа также должно быть UNSIGNED. Если поле первичного ключа имеет значение SIGNED, то поле внешнего ключа также должно быть подписано. Подумайте об этом так: какой бы столбец в одной таблице не был определен, как в SHOW CREATE TABLE, он должен иметь такое же определение в другой таблице.
Бен Кин

1
Обратите внимание, что это также может быть сделано с помощью одного запроса (может быть лучше в случае сбоя и т. Д.)
Stijn de Witt

6
Я должен был запустить "SET FOREIGN_KEY_CHECKS = 0;" перед выполнением команды ADD CONSTRAINT или SQL выдаст сообщение «Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено».
Эрин Гейер

2
Вы не просто запустить "SET FOREIGN_KEY_CHECKS = 0;" если вы получаете сообщение об ошибке «ограничение внешнего ключа не удается», у вас, очевидно, имеются неверные данные, которые вы должны исправить, иначе у вас возникнут более серьезные проблемы.
MazeChaZer

72

Просто используйте этот запрос, я пробовал его по моему сценарию, и он работает хорошо

ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);


15

проверьте эту ссылку. Это помогло мне с ошибкой 150: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

На моей голове две вещи приходят на ум.

  • Является ли ваш индекс внешнего ключа уникальным именем во всей базе данных (№ 3 в списке)?
  • Вы пытаетесь установить для таблицы PK значение NULL при обновлении (# 5 в списке)?

Я предполагаю, что проблема с установленным NULL при обновлении (если мои мозги не возвращаются сегодня, как это часто бывает ...).

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


13
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Но ваш стол имеет:

CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,

Она не может установить столбец Sprache в NULL , поскольку оно определяется как NOT NULL.


5

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

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;

Ура!


5

Как исправить Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. измените свою таблицу и добавьте к ней индекс ..

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. Теперь добавьте ограничение

    ALTER TABLE foreign_key_table
    ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
    REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
    ON UPDATE CASCADE;
    

Обратите внимание, если вы не добавите индекс, он не будет работать.

После 6 часов борьбы с ним я нашел решение, надеюсь, это спасет душу.


4

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

  1. Создать индекс
  2. Изменить стол

Я создал индекс для обоих. Когда я пытаюсь запустить, я получаю то же сообщение об ошибке, что и раньше. Когда я отказываюсь от части «при удалении при обновлении», она работает, но с неправильным действием «при удалении»;)
frgtv10

@ frgtv10 наиболее вероятные данные таблиц конфликтуют с "при удалении".
Максим Поль

3

попробуйте все в одном запросе

  ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

0

это в основном происходит потому, что ваши таблицы находятся в двух разных кодировках. Например, одна таблица, созданная в charset = utf-8, и другие таблицы созданы в CHARSET = latin1, так что вы хотите иметь возможность добавить внешний ключ к этим таблицам. используйте одну и ту же кодировку в обеих таблицах, тогда вы сможете добавить внешние ключи. ошибка 1005 неправильного формирования внешнего ключа может решить эту проблему


0

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


0

Шаг 1: запустить этот скрипт

SET FOREIGN_KEY_CHECKS=0;

шаг 2: добавить столбец

ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL

шаг 3: добавление внешнего ключа в добавляемый столбец

ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);

шаг 4: запустите этот скрипт

SET FOREIGN_KEY_CHECKS=1;

-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

Пример:-

ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)

1
Пожалуйста, добавьте некоторые пояснения к своему коду, чтобы другие могли извлечь из него урок
Нико Хаазе
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.