Сбой добавления внешнего ключа в MySQL с кодом ошибки 1005, номер 150 - PullRequest
14 голосов
/ 26 мая 2011

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

 ALTER TABLE `UserTransactions`.`ExpenseBackTransactions` 
   ADD CONSTRAINT `FK_EBTx_CustomAccountID`
   FOREIGN KEY (`CustomAccountID` )
   REFERENCES `UserTransactions`.`CustomAccounts` (`CustomAccountID`)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION,
   ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC) ;

и я продолжаю получать следующую ошибку:

Error Code: 1005
Can't create table './UserTransactions/#sql-187a_29.frm' (errno: 150)

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

UPDATE

Моя SHOW INNODB STATUS ошибка:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
110525 15:56:36 Error in foreign key constraint of table UserTransactions/#sql-187a_2c:

  FOREIGN KEY (`CustomAccountID` )
  REFERENCES `UserTransactions`.`CustomAccounts` (`CustomAccountID` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
, ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC):
Cannot resolve table name close to:
 (`CustomAccountID` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
, ADD INDEX `FK_EBTx_CustomAccountID` (`CustomAccountID` ASC)

Ответы [ 3 ]

27 голосов
/ 26 мая 2011

Здесь есть хороший контрольный список .

Ниже приведен список известных причин, о которых люди сообщали об ужасном errno 150:

  1. Тип и / или размер двух ключевых полей не совпадают. Например, если один равен INT (10), то ключевым полем также должно быть INT (10), а не INT (11) или TINYINT. Возможно, вы захотите подтвердить размер поля, используя SHOW CREATE TABLE, потому что Query Browser иногда визуально отображает только INTEGER для INT (10) и INT (11). Вы также должны проверить, что один не ПОДПИСАН, а другой НЕ ПОДПИСАН. Они оба должны быть абсолютно одинаковыми. (Подробнее о подписанных и неподписанных здесь).
  2. Одно из ключевых полей, на которое вы пытаетесь сослаться, не имеет индекса и / или не является первичным ключом. Если одно из полей в связи не является первичным ключом, необходимо создать индекс для этого поля. (спасибо Venkatesh и Erichero и Terminally Incoherent за этот совет)
  3. Имя внешнего ключа является дубликатом уже существующего ключа. Убедитесь, что имя вашего внешнего ключа является уникальным в вашей базе данных. Просто добавьте несколько случайных символов в конец имени вашего ключа, чтобы проверить это. (Спасибо Нильсу за этот совет)
  4. Одна или обе ваши таблицы являются таблицами MyISAM. Чтобы использовать внешние ключи, обе таблицы должны быть InnoDB. (На самом деле, если обе таблицы MyISAM, вы не получите сообщение об ошибке - просто не создаст ключ.) В Query Browser вы можете указать тип таблицы.
  5. Вы указали каскад ON DELETE SET NULL, но для соответствующего ключевого поля установлено значение NOT NULL. Это можно исправить, изменив каскад или установив в поле значения NULL. (Спасибо Сэмми и Джаммину)
  6. Убедитесь, что параметры Charset и Collate одинаковы как на уровне таблицы, так и на уровне отдельных полей для ключевых столбцов. (Спасибо FRR за этот совет)
  7. У вас есть значение по умолчанию (т.е. default = 0) в столбце внешнего ключа (спасибо Омару за подсказку)
  8. Одно из полей отношения является частью комбинированного (составного) ключа и не имеет собственного индивидуального индекса. Даже если у поля есть индекс как часть составного ключа, вы должны создать отдельный индекс только для этого ключевого поля, чтобы использовать его в ограничении. (Спасибо Алексу за этот совет)
  9. В вашем выражении ALTER есть синтаксическая ошибка или вы ошиблись при вводе одного из имен полей в отношениях (спасибо Christian & Mateo за подсказку)
  10. Имя вашего внешнего ключа превышает максимальную длину в 64 символа. (Спасибо Нилете за подсказку)
3 голосов
/ 26 мая 2011

По моему опыту, errno: 150 обычно указывает, что типы данных столбца FOREIGN KEY в таблице ключей и соответствующей таблице не идентичны.Убедитесь, что CustomAccounts.CustomAccountID и ExpenseBackTransactions.CustomAccountID точно такого же типа, включая UNSIGNED, если применимо.

Если это не поможет, пожалуйста, напишите SHOW CREATE TABLE ExpenseBackTransactions; и SHOW CREATE TABLE CustomAccounts;

0 голосов
/ 26 мая 2011

Catch 22. Внешним ключам нужны индексы.MySQL не упорядочивает этот запрос так, чтобы индекс существовал во время проверки внешнего ключа.Таким образом, сначала создайте индекс, затем добавьте внешний ключ в 2 отдельных запроса.

...