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)


1
По суті всі причини цієї помилки, ось вичерпний ресурс для того, що спричинює errno 150 (та errno 121 / інші помилки із зовнішнім ключем) у MySQL.
Джон Сміт

21
Я виявив, що стовпці повинні бути однаковими (навіть непідписаний прапор повинен відповідати).
Джастін Скілз

3
@JohnSmith ... куди?
Чарльз Вуд

3
Я пропоную прочитати цю публікацію в блозі, де вказано 10 можливих причин: verysimple.com/2006/10/22/…
Марк

@CharlesWood: " Джон Сміт ... бачив 6 квітня 1313 о 19:29 ", тобто за три місяці до вашого коментаря. У мене є страх, що таємниця "куди" не буде розкрита до кінця цього похмурого світу! :>
trejder

Відповіді:


167

З документації щодо обмежень MySQL - ІНОЗЕМНИЙ КЛЮЧ :

Якщо ви заново створили таблицю, яку випали, вона повинна мати визначення, яке відповідає обмеженням зовнішнього ключа, на яке посилається. Він повинен мати правильні назви та типи стовпців, а також на індексах посилальних ключів, як зазначено раніше. Якщо їх не влаштовує, MySQL повертає помилку 1005 і посилається на помилку 150 у повідомленні про помилку, що означає, що обмеження зовнішнього ключа було неправильно сформовано. Аналогічно, якщо ALTER TABLE не вдається через помилку 150, це означає, що визначення зміненого ключа було б неправильно сформовано для зміненої таблиці.


1
Чи можуть два стовпці з однієї таблиці посилатися на один стовпчик з іншого таблиці, де це ПК?
Євген

1
@Eugene: Кожен з двох стовпців може мати відношення зовнішнього ключа до ПК у іншій таблиці - не обидва стовпчики як єдине зовнішнє ключове відношення.
OMG Ponies

1
@OMGPonies: Дякую за відповідь на це запитання! .. Я шукав його ... Я також задав тут питання stackoverflow.com/questions/13487010/… . Хоча у мене є кілька хороших відповідей, але я хочу відповідати Whether its possible to write Nested Query for my problem? .. Я б просив вас, будь ласка, відповісти і на мене!
Grijesh Chauhan

19
Моєю помилкою була головна таблиця двигуна MyISAM та дочірньої таблиці InnoDB. Поточний скрипт create.sql використовував InnoDB для всіх таблиць, але у мене була дуже стара установка, де в першому скрипті використовувався MyISAM.
Кому

2
@Whome - Так, тут зіткнулися з тією ж проблемою.
aroth

96

Помилка 150 означає, що у вас проблема з іноземним ключем. Можливо, ключ на іноземному столі не точно такий же тип?


15
Дякую :) для мене типи даних INT, але один не підписаний, а інший
Anh Nguyen

6
Я часто натрапляю на BIGINTvs INTпри використанні генераторів схем.
Xeoncross

Я зіткнувся з тією ж проблемою, коли зовнішній ключ не є значенням INT. Стовпець повинен бути УНІКАЛЬНИМ, коли на нього посилається зовнішній ключ.
PhatHV

62

Ви можете отримати фактичне повідомлення про помилку, запустивши SHOW ENGINE INNODB STATUS;та шукаючи LATEST FOREIGN KEY ERRORу висновку.

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


7
Це насправді дуже корисно. Це вказує точну помилку.
Csongor Fagyal

Дякую. Прикро, що MySQL Workbench цим не користується.
вчений пілот

Дивовижно. Це так корисно. Повідомляє точну помилку. Моє було, зробивши стовпець NULLABLE, але встановив "on delete set null". Дуже дякую.
Абхішек Саїні

Якщо у вас є привілеї на вашому сервері :(
Christopher Smit

30

Типи даних повинні точно відповідати. Якщо ви маєте справу з типами varchar, таблиці повинні використовувати один і той самий параметр.


4
Дякуємо за біт співставлення
арахант

25

Я думаю, що всі ці відповіді, хоча і правильні, вводять в оману питання.

Фактична відповідь - це перед початком відновлення, якщо ви відновлюєте дамп-файл із зовнішніми ключами:

SET FOREIGN_KEY_CHECKS=0;

тому що, природно, відновлення буде створювати певні обмеження, перш ніж іноземний стіл навіть існує.


Це не спрацювало для мене, але все-таки видає помилку. Будь-які ідеї?
Йосип Астрахан

24

У деяких випадках ви можете зустріти це повідомлення про помилку, якщо між відповідними таблицями є різні двигуни. Наприклад, таблиця може використовувати InnoDB, а інша використовує MyISAM. Обоє повинні бути однаковими


Спасибі - це була моя проблема.
вчений пілот

Це було моє питання. Спасибі
thed0ctor

Це може статися, якщо ви створили sql файл таблиці innodb, використовуючи mysqldump, і вони були експортовані замість myisam talbes.
Amado Martinez

11

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

Якщо цього немає, вийміть оператор із зовнішнім ключем та додайте його після створення таблиці - ви отримаєте більш змістовне повідомлення про помилку щодо конкретної помилки обмеження.


10

Є досить багато речей, які можуть спричинити помилку 150, тому для людей, які шукають цю тему, ось що, на мою думку, є близьким до вичерпного списку (джерело Причини Errno 150 ):

Для errno 150 або errno 121, просто ввівши ПОКАЖИТИ СТАТУТ ДВИГАТЕЛЯ, існує розділ під назвою "ПОСЛІДНА ПОМИЛКА ІНТЕРНЕТ-КЛЮЧ". З цього приводу ви отримаєте дуже корисне повідомлення про помилку, яке, як правило, відразу скаже вам, у чому справа. Для його запуску потрібні привілеї SUPER, тому якщо у вас цього немає, вам просто доведеться перевірити наступні сценарії.

1) Типи даних не збігаються: типи стовпців повинні бути однаковими

2) Батьківські стовпці не індексуються (або індексуються в неправильному порядку)

3) Збірки стовпців не збігаються

4) Використання SET NULL у стовпці NOT NULL

5) Збір таблиці не відповідає: навіть якщо порівняння стовпців збігаються, у деяких версіях MySQL це може бути проблемою.

6) Батьківська колонка насправді не існує в батьківській таблиці. Перевірте правопис (і можливо пробіл на початку чи в кінці стовпця)

7) Один з індексів на одному з стовпців є неповним або стовпчик занадто довгий для повного індексу. Зауважте, що MySQL (якщо ви не налаштовуєте його) має максимальну довжину ключа одного стовпчика 767 байт (це відповідає стовпцю varchar (255) UTF)

Якщо ви отримали помилку 121, ось кілька причин:

1) Ім'я обмеження, яке ви вибрали, вже прийняте

2) У деяких системах, якщо в назвах ваших операторів та таблиць є різниця в регістрі. Це може вас вкусити, якщо ви переходите з одного сервера на інший, який має різні правила обробки справ.


У деяких версіях ви отримуєте errno 150, якщо таблиця не є innodb, але в деяких версіях вона просто виходить з ладу.
juacala

Дякую, це було чудово: | ------------------------ | ОСТАННЯ ПОМИЛКА ІНОЗЕМНОГО КЛЮЧУ | ------------------------ | Ви визначили умову SET NULL, хоча деякі з | стовпці визначаються як НІ NULL.
Сем Крічлі

8

Іноді MySQL просто супер дурний - я можу зрозуміти причину виникнення сторонніх ключів .. але в моєму випадку я просто скинув всю базу даних, і я все одно отримую помилку ... чому? я маю на увазі, вже немає бази даних ... і користувач sql, яким я користуюся, не має доступу до будь-яких інших db-серверів на сервері ... я маю на увазі, сервер "порожній" для поточного користувача, і я все одно отримую ця помилка? Вибачте, але я здогадуюсь, що MySQL бреше мені ... але я можу з цим впоратися :) Просто додайте ці два рядки SQL навколо вашої пустотливої ​​заяви:

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

Тепер sql має бути виконано ... Якщо у вас справді є проблема із зовнішнім ключем, вона з’явиться перед вами рядком, де ви знову ввімкнете чеки - це не вдасться потім .. але мій сервер просто тихий :)


Це може спричинити проблеми, якщо між стовпцем та стовпцем, на який він посилається, є фактичні відмінності. Наприклад. Скажімо, що посилається стовпець - це варчар (200), а референт - варчар (50), тоді при спробі каскаду може настати дивна поведінка. Я не стикався з проблемою, коли errno 150 видається через невідповідність даних.
juacala

Цікаве розуміння @juacala :) Мені смішно, тільки коли я стикався з цим, мій підхід завжди це фіксував ... до сьогодні щонайменше: D Але ми ніколи не припиняємо вчитися, правда;)
jebbie

Це фактично допомогло мені створити скрипт з ліквідним сценарієм. Сценарій працює бездоганно на MySQL> 5.5, але не вдався до версії 5.1.
delbertooo

4

Переглянувши відповіді вище та трохи експериментуючи, це ефективний спосіб вирішити помилки іноземних ключів у MySQL (1005 - помилка 150).

Щоб зовнішній ключ був належним чином створений, всі MySQL просять:

  • Усі посилаються ключі ОБОВ'ЯЗКОВО мають ПЕРВІЙНИЙ або УНІКАЛЬНИЙ індекс
  • Стовпець посилань ОБОВ'ЯЗКОВО повинен мати ідентичний тип даних стовпцю "Посилання".

Задовольте ці вимоги, і все буде добре.


4

Я зіткнувся з цією помилкою, коли переніс програму Windows в Linux. У Windows імена таблиць баз даних нечутливі до регістру, а в Linux - чутливі до регістру, ймовірно, через різницю файлової системи. Отже, на столі Windows Table1те саме table1, що і в REFERENCESобох table1і Table1працює. У Linux, коли застосунок використовувався table1замість того, Table1коли він створював структуру бази даних, я побачив помилку № 150; коли я зробив правильний регістр символів у Table1посиланнях, він також почав працювати на Linux. Отже, якщо нічого іншого не допомагає, переконайтеся, що REFERENCESви використовуєте правильний регістр символів у назві таблиці під час роботи в Linux.


Це теж був мій випадок! Переміщення сценарію з нечутливого до регістру (OS X) до чутливої ​​до регістру версії mysql (Debian).
mircealungu


3

Якщо таблиця PK створена в одному CHARSET, а потім ви створюєте таблицю FK в іншій 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;

3

Ця помилка може виникнути, якщо у двох таблицях є посилання, наприклад, одна таблиця - Студент, а інша - Освіта, і ми хочемо, щоб таблиця Освіта мала зовнішнє ключове посилання таблиці Студент. У цьому випадку тип даних стовпців для обох таблиць повинен бути однаковим, інакше це призведе до помилки.


3

У більшості випадків проблема виникає через різницю ENGINE. Якщо батьківський створений InnoDB, тоді посилання таблиці повинні бути створені MyISAM і навпаки


3

У моєму випадку. У мене виникли проблеми з двигуном і діаграмою, оскільки мій сервер зміни хостингу хостингу, а мої нові таблиці були MyISAM, але мої старі таблиці - InnoDB. Просто я змінився.


Це було правильно для мене, тому що я змінював базу даних, яку я не робив.
FonzTech

3

зазвичай, невідповідність між зовнішнім ключем та первинним ключем викликає помилку: 150.

Зовнішній ключ повинен мати той самий тип даних , що і первинний ключ . Крім того , якщо первинний ключ є без знака , то зовнішній ключ повинен бути також без знака .


3

У мене був такий самий випуск. Це було пов'язано зі зібранням стовпців та набором символів . Переконайтеся, що набір символів та зіставлення символів повинні бути однаковими для обох стовпців у двох таблицях. Якщо ви хочете встановити на цьому зовнішній ключ. Приклад. Якщо ви кладете іноземний ключ у стовпчик userID таблиці userImage, що посилається на стовпець userID таблиці таблиць користувачів. Потім зіставлення повинно бути однаковим, що є utf8_general_ci та символьним набором utf8 для обох стовпців таблиць. Зазвичай при створенні таблиці mysql приймає ці дві конфігурації з налаштувань сервера.


Чому я раніше не бачив цього поїста !? Я витратив годину, з'ясовуючи першопричину. Це була шахта в моєму випадку. Посилання та таблиці, що посилаються, повинні мати однакову схему.
Sujit Joshi

2

Будь ласка, переконайтеся, що і ваш стовпчик основного ключа, і посилальний стовпець мають однакові типи даних та атрибути (неподписані, двійкові, неподписані нульове заповнення тощо).


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 НІКОЛИ НЕ БУДЕ ВИКОНАТИ ВАШЕ ОБМЕЖЕННЯ

Важливо пам’ятати, що за звичайних обставин, якщо ви планували свою базу даних заздалегідь, і застосували обмеження до введення даних, цього конкретного сценарію вдасться уникнути.

Простіший підхід, щоб уникнути цього готча, - це

  • Збережіть дані таблиць баз даних
  • Обрізати дані таблиці (та артефакти таблиці, тобто індекси тощо)
  • Застосовуйте обмеження
  • Імпортуйте свої дані

Я сподіваюся, що це комусь допоможе


1

Можливо, це допоможе? Визначення стовпця первинного ключа має бути точно таким же, як стовпчик із зовнішнім ключем.


1

Переконайтеся, що всі таблиці можуть підтримувати зовнішній ключ - двигун InnoDB


1

Стовпець таблиці PARENT, на який ви посилаєтесь з дочірньої таблиці, повинен бути унікальним. Якщо його немає, викликайте помилку не 150.


напевно, варто було б додати трохи детальніше - наприклад, конкретні назви стовпців та таблиць
Джонатан

1

У мене була подібна проблема під час завантаження бази даних Django mysql за допомогою однієї таблиці. Мені вдалося виправити проблему, перевантаживши базу даних у текстовий файл, перемістивши відповідну таблицю до кінця файла за допомогою emacs та імпортувавши модифікований файл дамп-файлу у новий екземпляр.

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. Моє трапляється під час створення таблиці при посиланні іноземного ключа на іншу таблицю, яка ще не була створена. Це послідовність існування таблиці перед посиланням.

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


1

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.