2009-05-05 2 views
16

Когда я исполняю следовать два запроса (я раздели их к абсолютно необходимым):MySql Ошибка 150 - Внешние ключи

mysql> CREATE TABLE foo(id INT PRIMARY KEY); 
Query OK, 0 rows affected (0.01 sec) 

mysql> CREATE TABLE bar (id INT, ref INT, FOREIGN KEY (ref) REFERENCES foo(id)) ENGINE InnoDB; 

Я получаю следующее сообщение об ошибке: ERROR 1005 (HY000): Не может create table './test/bar.frm' (errno: 150)

Где моя ошибка? Я не нашел его, глядя на это полчаса.

ответ

29

От FOREIGN KEY Constraints

If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message.

Мой подозрение в том, что это потому, что вы не создавали foo как InnoDB, как и все остальное выглядит нормально.

Edit: из одной и той же странице -

Both tables must be InnoDB tables and they must not be TEMPORARY tables.

+0

Немного быстрого тестирования, создающего 'foo', как указано выше, с MyISAM и' bar' с InnoDB, предполагает, что это так - попробуйте дважды проверить тип таблицы для 'foo'. – Rob

+0

+1 для «Обе таблицы должны быть таблицами InnoDB», спасибо большое! – sanbhat

+1

Даже когда обе таблицы были InnoDB, у меня все еще была такая же проблема. Я исправил его, создав индекс в указанной таблице перед созданием внешнего ключа. – IROEGBU

1

У меня была такая же проблема, для тех, кто испытывает это также:

проверить имя таблицы из указанной таблицы

я имел забыли «s» в конце моей таблицы.

eg table Клиент -> Клиенты

:)

0

У меня была такая же проблема, и причина заключалась в том, что «сортировка» столбцов была другой. Один из них был latin1 в то время как другой был utf8

9

Вы можете использовать команду SHOW ENGINE INNODB STATUS

+0

Спасибо! Спасенный день –

+0

Согласен! Он показывает раздел «Последняя ошибка внешнего ключа», который в моем случае сказал мне, что имя целевого поля ограничения внешнего ключа не было найдено. Это более полезно, чем просто «Ошибка 150» ;-) –

+0

В моем случае я забыл установить столбец, чтобы разрешить NULL, и наложил SET NULL на ограничение. Но я только выяснил причину, запустив «SHOW ENGINE INNODB STATUS» –

1

Помимо формы и многие другие причины, чтобы в конечном итоге с MySql ошибка 150 (при использовании InnoDB), одной из вероятных причин является неопределенным KEY в инструкции create таблицы, содержащей имя столбца, на которое ссылается как внешний ключ в относительной таблице.

Скажем создать заявление мастер таблицы -

CREATE TABLE 'master_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'record_id' char(10) NOT NULL,
 'name' varchar(50) NOT NULL DEFAULT '',
 'address' varchar(200) NOT NULL DEFAULT '',
 PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

и создать синтаксис для relative_table таблицы, где ограничение внешнего ключа устанавливается из главной таблицы -

CREATE TABLE 'relative_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'salary' int(10) NOT NULL DEFAULT '',
 'grade' char(2) NOT NULL DEFAULT '',
 'record_id' char(10) DEFAULT NULL,
 PRIMARY KEY ('id'),
 CONSTRAINT 'fk_slave_master' FOREIGN KEY ('record_id') REFERENCES 'master' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Этот скрипт определенно закончится MySql Error 150 при использовании InnoDB.

Чтобы решить эту проблему, нам нужно добавить KEY для Столбца record_id в master_table таблицы, а затем ссылаться на relative_table таблиц, которые будут использоваться в качестве foreign_key.

Наконец, создать заявление для master_table, будет -

CREATE TABLE 'master_table' (
 'id' int(10) NOT NULL AUTO_INCREMENT,
 'record_id' char(10) NOT NULL,
 'name' varchar(50) NOT NULL DEFAULT '',
 'address' varchar(200) NOT NULL DEFAULT '',
 PRIMARY KEY ('id'),
 KEY 'record_id' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4

Для создания внешнего ключа,

  1. как основной столбец и ссылка на столбец должен иметь такое же определение.
  2. Оба стола двигателя должны быть InnoDB.

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

alter table [имя таблицы] ENGINE = InnoDB;

+2

«должно иметь такое же определение» было такое же кодирование кодировки для меня – gengisdave

+0

«должно иметь одно и то же определение» для меня были те же самые флаги столбцов для меня: существующий первичный ключ, на который я ссылался был UNSIGNED, поэтому мне пришлось создать столбец моей новой таблицы, который также был включен в внешний ключ на первом – cellepo

0

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