MySQL: не могу создать таблицу (номер ошибки: 150)

156

Я пытаюсь импортировать файл .sql и не удается создать таблицы.

Вот запрос, который не удался:

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

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

MySQL: не удается создать таблицу «./dbname/data.frm» (номер ошибки: 150)

gtilx
источник
1
По существу для всех причин этой ошибки, вот исчерпывающий ресурс для того, что вызывает ошибки errno 150 (и errno 121 / другие ошибки внешнего ключа) в MySQL.
Джон Смит
21
Я обнаружил, что столбцы должны быть идентичны (даже флаг без знака должен совпадать).
Джастин Скилз
3
@JohnSmith ... где?
Чарльз Вуд
3
Я предлагаю прочитать этот пост в блоге, в котором перечислены 10 возможных причин: verysimple.com/2006/10/22/…
Марк Эмери
@CharlesWood: « Джон Смит ... видел 6 апреля '13 в 19:29 », то есть примерно за три месяца до вашего комментария. У меня есть страх, что тайна «где» не будет раскрыта до конца этого тупого мира! :>
Трейдер

Ответы:

167

Из документации по ограничениям для MySQL - FOREIGN KEY :

Если вы воссоздаете таблицу, которая была удалена, у нее должно быть определение, соответствующее ограничениям внешнего ключа, ссылающимся на нее. У него должны быть правильные имена и типы столбцов, и он должен иметь индексы на ссылочных ключах, как указано ранее. Если они не удовлетворены, MySQL возвращает ошибку 1005 и ссылается на ошибку 150 в сообщении об ошибке, что означает, что ограничение внешнего ключа было сформировано неправильно. Точно так же, если ALTER TABLE завершается ошибкой из-за ошибки 150, это означает, что определение внешнего ключа будет неправильно сформировано для измененной таблицы.

OMG пони
источник
1
Могут ли два столбца из одной таблицы ссылаться на один столбец из другой таблицы, где это PK?
Евгений
1
@Eugene: Каждый из двух столбцов может иметь отношение внешнего ключа к PK в другой таблице, а не оба столбца как одно отношение внешнего ключа.
OMG Ponies
1
@OMGPonies: Спасибо, что ответили на этот вопрос! .. Я искал его ... Я также задал вопрос здесь stackoverflow.com/questions/13487010/… .... Хотя у меня есть несколько хороших ответов, но я хочу соответствовать Whether its possible to write Nested Query for my problem? ..Я хотел бы попросить вас ответить мне тоже!
Грижеш Чаухан
19
Моя ошибка была в главной таблице MyISAM и дочерней таблице InnoDB engine. Текущий скрипт create.sql использовал InnoDB для всех таблиц, но у меня была очень старая установка, где первый скрипт использовал MyISAM.
Whome
2
@Whome - Да, столкнулся с той же проблемой здесь.
Аромат
96

Ошибка 150 означает, что у вас есть проблема с вашим внешним ключом. Возможно, ключ на чужой таблице не тот же тип?

Дэн МакГрат
источник
15
Спасибо :) для меня, типы данных INT, но один без знака, а другой нет
Anh Nguyen
6
Я часто сталкиваюсь с BIGINTvs INTпри использовании генераторов схемы.
Xeoncross
Я столкнулся с той же проблемой, когда внешний ключ не является значением INT. Столбец должен быть УНИКАЛЬНЫМ, когда внешний ключ ссылается на него.
PhatHV
62

Вы можете получить реальное сообщение об ошибке, запустив SHOW ENGINE INNODB STATUS;и затем выполнив поиск LATEST FOREIGN KEY ERRORв выходных данных.

Источник: ответ другого пользователя на похожий вопрос

Денилсон Са Майя
источник
7
Это на самом деле очень полезно. Это говорит вам точную ошибку.
Чонгор Фагьял,
Спасибо. Обидно, что MySQL Workbench не использует это.
скипилот
Потрясающие. Это так полезно. Сообщает вам точную ошибку. Мое было, чтобы сделать столбец NULLABLE, но установил "при удалении набора ноль". Огромное спасибо.
Абхишек Сайни
Если у вас есть привилегии на вашем сервере :(
Кристофер Смит
30

Типы данных должны точно соответствовать. Если вы имеете дело с типами varchar, таблицы должны использовать одинаковое сопоставление.

Эсбен Сков Педерсен
источник
4
Спасибо за сравнение.
арахант
25

Я думаю, что все эти ответы, хотя и правильные, вводят в заблуждение вопрос.

Фактический ответ таков: перед началом восстановления, если вы восстанавливаете файл дампа с помощью внешних ключей:

SET FOREIGN_KEY_CHECKS=0;

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

Colin
источник
Это не помогло мне, но выдает ошибку. Любые идеи?
Джозеф Астрахан
24

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

число Пи.
источник
Спасибо - это была моя проблема.
скипилот
Это была моя проблема. Спасибо
thed0ctor
Это может произойти, если вы создали файл sql таблицы innodb, используя mysqldump, и вместо этого они были экспортированы как myisam talbes.
Амадо Мартинес
11

Ошибка № 150 означает сбой ограничения внешнего ключа. Вы, вероятно, создаете эту таблицу перед таблицей, от которой зависит внешний ключ (таблица keywords). Сначала создайте эту таблицу, и она должна работать нормально.

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

Эран Гальперин
источник
10

Есть несколько вещей, которые могут вызвать ошибку errno 150, поэтому для людей, ищущих эту тему, вот что я думаю, это почти полный список (источник Причины ошибки Errno 150 ):

Для errno 150 или errno 121, просто набрав в SHOW ENGINE INNODB STATUS, есть раздел под названием «ПОСЛЕДНЯЯ ОШИБКА ИНОСТРАННЫХ КЛЮЧЕЙ». При этом он даст вам очень полезное сообщение об ошибке, которое, как правило, сразу скажет вам, в чем дело. Вам нужны привилегии SUPER для его запуска, поэтому, если у вас его нет, вам просто нужно протестировать следующие сценарии.

1) Типы данных не совпадают: типы столбцов должны быть одинаковыми

2) Родительские столбцы не проиндексированы (или проиндексированы в неправильном порядке)

3) Столбцы столбцов не совпадают

4) Использование SET NULL в столбце NOT NULL

5) Совпадения таблиц не совпадают: даже если сопоставления столбцов совпадают, в некоторых версиях MySQL это может быть проблемой.

6) Родительский столбец фактически не существует в родительской таблице. Проверьте орфографию (и, возможно, пробел в начале или конце столбца)

7) Один из индексов в одном из столбцов является неполным или столбец слишком длинный для полного индекса. Обратите внимание, что максимальная длина ключа в одном столбце (если вы его не настроите) составляет 767 байт (это соответствует столбцу UTF varchar (255))

В случае, если вы получите errno 121, вот несколько причин:

1) Выбранное вами имя ограничения уже занято

2) В некоторых системах, если есть разница в именах ваших операторов и таблиц. Это может укусить вас, если вы переходите с одного сервера на другой, у которого разные правила обработки обращений.

juacala
источник
В некоторых версиях вы получаете errno 150, если таблица не innodb, но в некоторых версиях она просто молча терпит неудачу.
Juacala
Спасибо, это было здорово: | ------------------------ | ПОСЛЕДНЯЯ ОШИБКА ИНОСТРАННОГО КЛЮЧА ------------------------ | Вы определили условие SET NULL, хотя некоторые из | столбцы определены как NOT NULL.
Сэм Кричли
8

Иногда MySQL просто супер глупый - я могу понять причину внешних ключей ... но в моем случае я просто отбросил всю базу данных, и все равно получаю ошибку ... почему? я имею в виду, что базы данных больше нет ... и используемый мной sql-пользователь не имеет доступа ни к каким другим БД на сервере ... я имею в виду, что сервер "пуст" для текущего пользователя, и я все еще получаю эта ошибка? Извините, но я предполагаю, что MySQL лжет мне ... но я могу с этим справиться :) Просто добавьте эти две строки SQL вокруг вашего дурацкого утверждения:

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

Теперь sql должен быть выполнен ... Если у вас действительно есть проблема с внешним ключом, он появится у вас на линии, где вы снова включите проверки - тогда это не получится ... но мой сервер просто тихий :)

jebbie
источник
Это может вызвать проблемы, если на самом деле есть различия между столбцом и столбцом, на который он ссылается. Например. Скажем, указанный столбец - это varchar (200), а ссылающийся - varchar (50), тогда при попытке каскада может возникнуть странное поведение. Я не сталкивался с проблемой, когда errno 150 выдается из-за несоответствия данных.
Juacala
Интересная идея @juacala :) Забавно только то, что всякий раз, когда я сталкивался с этим, мой подход всегда исправлял это ... по крайней мере, до сегодняшнего дня: D Но мы никогда не прекращаем учиться, верно;)
Джебби
Это на самом деле помогло мне сгенерировать сценарий ликвидазы. Сценарий работал безупречно на MySQL> 5.5, но не получился для версии 5.1.
Delbertooo
4

После изучения ответов выше и небольшого эксперимента это эффективный способ решения ошибок внешнего ключа в MySQL (1005 - ошибка 150).

Для правильного создания внешнего ключа MySQL запрашивает:

  • Все ссылочные ключи ДОЛЖНЫ иметь индекс PRIMARY или UNIQUE.
  • Ссылочный столбец снова ДОЛЖЕН иметь тип данных, идентичный ссылочному столбцу.

Удовлетворите эти требования и все будет хорошо.

Дэвис Малези
источник
4

Я столкнулся с этой ошибкой, когда перенес приложение Windows в Linux. В Windows имена таблиц базы данных нечувствительны к регистру, а в Linux они чувствительны к регистру, вероятно, из-за различий в файловой системе. Итак, на Windows таблица Table1такая же, как table1и на REFERENCESобоих table1и Table1работает. В Linux, когда приложение использовалось table1вместо того, Table1чтобы создавать структуру базы данных, я видел ошибку # 150; когда я сделал правильный регистр символов в Table1ссылках, он начал работать и в Linux. Так что, если больше ничего не помогает, убедитесь, что REFERENCESвы используете правильный символ в имени таблицы при работе в Linux.

Vitalii
источник
Это был и мой случай! Перемещение скрипта из регистронезависимого (OS X) в регистрозависимую версию mysql (Debian).
mircealungu
3

Измените движки ваших таблиц, только innoDB поддерживает внешние ключи

Lappies
источник
3

Если таблица PK создается в одном CHARSET, а затем вы создаете таблицу FK в другом CHARSET .. то также вы можете получить эту ошибку ... Я тоже получил эту ошибку, но после изменения charset на PK charset, то она была выполнена без ошибок

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;
tinku
источник
3

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

манзаруль хак
источник
3

В большинстве случаев проблема заключается в разнице ENGINE. Если родительский объект создается InnoDB, то ссылочные таблицы должны создаваться MyISAM и наоборот.

Сунил Кумар Моханты
источник
3

В моем случае. У меня были проблемы с engine и charset, потому что мой сервер хостинга изменил настройки и мои новые таблицы были MyISAM, но мои старые таблицы - InnoDB. Просто я изменился.

Игнасио Эрнандес
источник
Это было правильно для меня, потому что я изменял базу данных, созданную не мной.
FonzTech
3

обычно несоответствие между внешним ключом и первичным ключом вызывает ошибку: 150.

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

Ракеш
источник
3

У меня была такая же проблема. Это было связано с колонкой таблицы Collation и набора символов . Убедитесь, что набор символов и сопоставление должны быть одинаковыми для обоих столбцов в двух таблицах. Если вы хотите установить внешний ключ на это. Пример - если вы поместите внешний ключ в столбец userID таблицы userImage, ссылающийся на столбец userID таблицы users. Тогда параметры сортировки должны быть такими же, как utf8_general_ci и набор символов utf8 для обоих столбцов таблиц. Обычно при создании таблицы mysql берет эти две конфигурации из настроек сервера.

Кумар, Сушил
источник
Почему я раньше не видел этот вид !? Я потратил час на выяснение первопричины. Это была кодировка в моем случае. Ссылочные и ссылочные таблицы должны иметь одну и ту же кодировку.
Суджит Джоши
2

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

Basit
источник
2

Реальный крайний случай - это когда вы использовали инструмент MySQL (в моем случае Sequel Pro) для переименования базы данных. Затем создал базу данных с тем же именем.

Это сохранило ограничения внешнего ключа для того же имени базы данных, поэтому переименованная база данных (например, my_db_renamed) имела ограничения внешнего ключа во вновь созданной базе данных (my_db)

Не уверен, что это ошибка в Sequel Pro, или если какой-то вариант использования требует такого поведения, но это стоило мне большую часть утра: /

Хим
источник
2

У меня была такая же ошибка. В моем случае причиной ошибки было то, что в ограничении был оператор ON DELETE SET NULL, в то время как поле, в которое я поместил ограничение в его определении, содержало оператор NOT NULL. Разрешение NULL в поле решило проблему.

Вилберт ван Димен
источник
2

Я столкнулся с такой проблемой при создании БД из текстового файла.

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

Я просто написал вышеупомянутые строки Create.batи запустил файл bat.

Моя ошибка в порядке выполнения в моих файлах sql. Я попытался создать таблицу с первичным ключом и внешним ключом. Во время работы он будет искать справочную таблицу, но таблиц там нет. Так что он вернет такие ошибки.

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

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

У меня была похожая проблема, но моя была в том, что я добавлял новое поле в существующую таблицу, в которой были данные, а новое поле ссылалось на другое поле из родительской таблицы, а также имело определение NOT NULL и без каких-либо ЗНАЧЕНИЙ ПО УМОЛЧАНИЮ. - Я выяснил причину, по которой вещи не работали, потому что

  1. Моему новому полю нужно было автоматически заполнить пустые поля значением из родительской таблицы в каждой записи, прежде чем можно будет применить ограничение. Каждый раз, когда накладывается ограничение, необходимо сохранить целостность данных таблицы без изменений. Внедрение ограничения (внешнего ключа), хотя некоторые записи в базе данных не имеют значений из родительской таблицы, означало бы, что данные повреждены, поэтому MySQL НИКОГДА НЕ УТВЕРЖДАЕТ ВАШУ ОГРАНИЧЕНИЕ

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

Более простой подход, чтобы избежать этой ошибки, заключается в

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

Я надеюсь, что это поможет кому-то

chitwarnold
источник
1

Возможно, это поможет? Определение столбца первичного ключа должно точно соответствовать столбцу внешнего ключа.

Mukus
источник
1

Убедитесь, что все таблицы могут поддерживать внешний ключ - движок InnoDB

joksy82
источник
1

Столбец таблицы PARENT, на которую вы ссылаетесь из дочерней таблицы, должен быть уникальным. Если это не так, вызвать ошибку № 150.

Дила Рам Гурунг
источник
вероятно, стоит добавить немного больше подробностей - например, имена конкретных столбцов и таблиц
Джонатан
1

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

HTH Uwe

пылесос
источник
1

Я исправил проблему, заставив переменную принять null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
Фахми
источник
1

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

Решение: сначала создайте родительские таблицы, прежде чем создавать дочернюю таблицу с внешним ключом.

Ronit
источник
1

Создайте таблицу без внешнего ключа, затем установите внешний ключ отдельно.

stuckhelper
источник