Додати зовнішній ключ до існуючої таблиці


324

Я хочу додати зовнішній ключ до таблиці під назвою "каталог".

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
Я не посилаюсь на два поля авто-посилення. katalog.Sprache (не авто) -> sprache.ID (auto)
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 у питанні, тип і знак полів повинні відповідати. Отже, якщо ваш основний ключ у таблиці пошуку не підписаний, то поле зовнішнього ключа також повинно бути НЕ ЗНАЧЕНО. Якщо поле первинного ключа є ПІДТВОРЕНО, то поле іноземного ключа також має бути підписане. Подумайте про це так: незалежно від того, що стовпець в одній таблиці визначений як у 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. Змінити таблицю

Я створив індекс для обох. Коли я намагаюся запустити, я отримую те саме повідомлення про помилку, як і раніше. Коли я відмовляюсь від частини "on delete on update", вона працює, але при неправильній дії "on delete";)
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.