MySQL: nie można utworzyć tabeli (errno: 150)

156

Próbuję zaimportować plik .sql i jego niepowodzenie podczas tworzenia tabel.

Oto zapytanie, które kończy się niepowodzeniem:

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;    

Wyeksportowałem plik .sql z tej samej bazy danych, porzuciłem wszystkie tabele, a teraz próbuję go zaimportować. Dlaczego to się nie udaje?

MySQL: Can't create table './dbname/data.frm' (errno: 150)

gtilx
źródło
1
W celu zapoznania się z wszystkimi przyczynami tego błędu, tutaj znajduje się wyczerpujące źródło informacji o przyczynach błędów errno 150 (i errno 121 / innych kluczy obcych) w MySQL.
John Smith
21
Odkryłem, że kolumny muszą być identyczne (nawet flaga bez znaku musi pasować).
Justin Skiles
3
@JohnSmith ... gdzie?
Charles Wood
3
Proponuję przeczytaniu tego blogu, że listy 10 możliwych przyczyn: verysimple.com/2006/10/22/...
Mark Amery
@CharlesWood: „ John Smith ... widziany 6 kwietnia 2013 o 19:29 ”, czyli około trzy miesiące przed Twoim komentarzem. Boję się, że tajemnica „gdzie” nie zostanie ujawniona przed końcem tego tępego świata! :>
trejder

Odpowiedzi:

167

Z dokumentacji MySQL - ograniczenia klucza obcego :

Jeśli ponownie utworzysz usuniętą tabelę, musi ona mieć definicję zgodną z powiązanymi z nią ograniczeniami klucza obcego. Musi mieć poprawne nazwy i typy kolumn oraz musi mieć indeksy przywoływanych kluczy, jak wspomniano wcześniej. Jeśli nie są one spełnione, MySQL zwraca błąd 1005 i odsyła do błędu 150 w komunikacie o błędzie, co oznacza, że ​​ograniczenie klucza obcego nie zostało poprawnie utworzone. Podobnie, jeśli ALTER TABLE nie powiedzie się z powodu błędu 150, oznacza to, że definicja klucza obcego zostanie niepoprawnie utworzona dla zmienionej tabeli.

Kucyki OMG
źródło
1
Czy dwie kolumny z jednej tabeli mogą odwoływać się do jednej kolumny z innej tabeli, gdzie jest to PK?
Eugene
1
@Eugene: każda z dwóch kolumn może mieć relację klucza obcego z PK w innej tabeli - a nie obie kolumny jako pojedyncza relacja klucza obcego.
OMG Kucyki
1
@OMGPonies: Dziękuję za odpowiedź na to pytanie! .. Szukałem tego ... Zadałem tutaj również pytanie stackoverflow.com/questions/13487010/ ... .... Chociaż mam kilka dobrych odpowiedzi, ale chcę być zgodny Whether its possible to write Nested Query for my problem? ..Proszę, żebyś też mi odpowiedziała!
Grijesh Chauhan
19
Mój błąd polegał na tym, że tabela główna miała silnik MyISAM i silnik tabeli potomnej InnoDB. Obecny skrypt create.sql używał InnoDB dla wszystkich tabel, ale miałem bardzo starą instalację, w której pierwszy skrypt używał MyISAM.
Kogo
2
@Whome - tak, napotkałem tutaj ten sam problem.
aroth
96

Błąd 150 oznacza, że ​​masz problem z kluczem obcym. Być może klucz na stole obcym nie jest dokładnie tego samego typu?

Dan McGrath
źródło
15
Dzięki :) Dla mnie typy danych to INT, ale jeden bez znaku, a drugi nie
Anh Nguyen
6
Często napotykam BIGINTvs INTpodczas korzystania z generatorów schematów.
Xeoncross
Napotkałem ten sam problem, gdy klucz obcy nie ma wartości INT. Kolumna musi być UNIKALNA, gdy odnosi się do niej klucz obcy.
PhatHV
62

Możesz uzyskać rzeczywisty komunikat o błędzie, uruchamiając, SHOW ENGINE INNODB STATUS;a następnie wyszukując LATEST FOREIGN KEY ERRORdane wyjściowe.

Źródło: odpowiedź innego użytkownika na podobne pytanie

Denilson Sá Maia
źródło
7
W rzeczywistości jest to bardzo przydatne. Podaje dokładny błąd.
Csongor Fagyal
dzięki. Szkoda, że ​​MySQL Workbench tego nie wykorzystuje.
scipilot
Niesamowite. To jest bardzo pomocne. Informuje o dokładnym błędzie. Mój był taki, że uczynił kolumnę NULLABLE, ale ustawił „przy usuwaniu zestaw zerowy”. Dziękuję bardzo.
Abhishek Saini
Jeśli masz uprawnienia na swoim serwerze :(
Christopher Smit
30

Typy danych muszą dokładnie pasować. Jeśli masz do czynienia z typami varchar, tabele muszą używać tego samego sortowania.

Esben Skov Pedersen
źródło
4
Dziękuję za porównanie.
arahant
25

Myślę, że wszystkie te odpowiedzi, choć poprawne, wprowadzają w błąd pytanie.

Właściwa odpowiedź jest taka, zanim zaczniesz przywracanie, jeśli przywracasz plik zrzutu z kluczami obcymi:

SET FOREIGN_KEY_CHECKS=0;

ponieważ naturalnie przywracanie będzie tworzyło pewne ograniczenia, zanim jeszcze istnieje obca tabela.

colin
źródło
Nie pomogło mi to, nadal daje błąd. Jakieś pomysły?
Joseph Astrahan,
24

W niektórych przypadkach możesz napotkać ten komunikat o błędzie, jeśli między powiązanymi tabelami znajdują się różne silniki. Na przykład jedna tabela może używać InnoDB, podczas gdy druga używa MyISAM. Obie muszą być takie same

Liczba Pi.
źródło
Dzięki - to był mój problem.
scipilot
To był mój problem. Dzięki
thed0ctor
Może się tak zdarzyć, jeśli utworzyłeś plik sql tabeli innodb za pomocą mysqldump i zamiast tego zostały wyeksportowane jako myisam talbes.
Amado Martinez,
11

Błąd nr. 150 oznacza błąd ograniczenia klucza obcego. Prawdopodobnie tworzysz tę tabelę przed tabelą, od której zależy klucz obcy (tabela keywords). Utwórz najpierw tę tabelę i powinna działać dobrze.

Jeśli tak się nie stanie, usuń instrukcję klucza obcego i dodaj ją po utworzeniu tabeli - otrzymasz bardziej zrozumiały komunikat o błędzie dotyczący określonego niepowodzenia ograniczenia.

Eran Galperin
źródło
10

Istnieje wiele rzeczy, które mogą powodować errno 150, więc dla osób szukających w tym temacie, moim zdaniem, jest to lista bliska wyczerpującej (źródło Przyczyny Errno 150 ):

W przypadku errno 150 lub errno 121, po prostu wpisując SHOW ENGINE INNODB STATUS, pojawia się sekcja o nazwie "LATEST FOREIGN KEY ERROR". Pod tym hasłem wyświetli bardzo pomocny komunikat o błędzie, który zazwyczaj od razu powie Ci, o co chodzi. Potrzebujesz SUPER uprawnień, aby go uruchomić, więc jeśli ich nie masz, musisz po prostu przetestować następujące scenariusze.

1) Nie pasują typy danych: typy kolumn muszą być takie same

2) Kolumny nadrzędne niezindeksowane (lub zindeksowane w niewłaściwej kolejności)

3) Kolumny nie pasują do siebie

4) Użycie SET NULL na kolumnie NOT NULL

5) Kolacje tabel nie są zgodne: nawet jeśli sortowania kolumn są zgodne, w niektórych wersjach MySQL może to być problem.

6) Kolumna nadrzędna w rzeczywistości nie istnieje w tabeli nadrzędnej. Sprawdź pisownię (i być może spację na początku lub na końcu kolumny)

7) Jeden z indeksów na jednej z kolumn jest niekompletny lub kolumna jest za długa, aby uzyskać pełny indeks. Zauważ, że MySQL (chyba że go zmodyfikujesz) ma maksymalną długość klucza pojedynczej kolumny wynoszącą 767 bajtów (odpowiada to kolumnie varchar (255) UTF)

Jeśli otrzymasz errno 121, oto kilka przyczyn:

1) Wybrana nazwa ograniczenia jest już zajęta

2) W niektórych systemach, jeśli występuje różnica wielkości liter w instrukcjach i nazwach tabel. Może cię to ugryźć, jeśli przejdziesz z jednego serwera na inny, na którym obowiązują inne zasady obsługi spraw.

juacala
źródło
W niektórych wersjach otrzymasz errno 150, jeśli tabela nie jest innodb, ale w niektórych wersjach po prostu cicho zawiedzie.
juacala
Dzięki, to było świetne: | ------------------------ | NAJNOWSZY BŁĄD KLUCZA ZAGRANICZNEGO | ------------------------ | Zdefiniowałeś warunek SET NULL, chociaż niektóre | kolumny są zdefiniowane jako NIE NULL.
Sam Critchley
8

Czasami MySQL jest po prostu super głupi - rozumiem przyczynę kluczy obcych ... ale w moim przypadku właśnie porzuciłem całą bazę danych i nadal otrzymuję błąd ... dlaczego? mam na myśli, że nie ma już bazy danych ... a użytkownik sql, którego używam, nie ma dostępu do żadnej innej bazy danych na serwerze ... mam na myśli, że serwer jest "pusty" dla bieżącego użytkownika i nadal otrzymuję ten błąd? Przepraszam, ale myślę, że MySQL mnie okłamuje ... ale sobie z tym poradzę :) Po prostu dodaj te dwie linie SQL do swojej pieprzonej instrukcji:

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

Teraz sql powinno zostać wykonane ... Jeśli naprawdę masz problem z kluczem obcym, pojawi się on przy linii, w której ponownie włączysz sprawdzanie - to się wtedy nie powiedzie ... ale mój serwer jest po prostu cichy :)

jebbie
źródło
Może to powodować problemy, jeśli rzeczywiście istnieją różnice między kolumną a kolumną, do której się odwołuje. Na przykład. Powiedzmy, że kolumna, do której się odwołujemy, to varchar (200), a strona odsyłająca to varchar (50). Nie natknąłem się na problem polegający na wystawianiu errno 150 z powodu niezgodności danych.
juacala
Ciekawe spostrzeżenie @juacala :) Zabawne jest dla mnie tylko to, że ilekroć na to wpadłem, moje podejście zawsze to naprawiało ... przynajmniej do dziś: D Ale my nigdy nie przestajemy się uczyć, prawda;)
jebbie
To faktycznie pomogło mi w wygenerowaniu skryptu liquibase. Skrypt działał bezbłędnie na MySQL> 5.5, ale nie działał na wersji 5.1.
delbertooo
4

Po przejrzeniu powyższych odpowiedzi i trochę poeksperymentowaniu, jest to skuteczny sposób na rozwiązanie błędów klucza obcego w MySQL (1005 - błąd 150).

Aby klucz obcy został poprawnie utworzony, MySQL prosi tylko o:

  • Wszystkie przywoływane klucze MUSZĄ mieć indeks PRIMARY lub UNIQUE.
  • Ponownie kolumna odniesienia MUSI mieć identyczny typ danych jak kolumna odniesienia.

Spełnij te wymagania, a wszystko będzie dobrze.

Davies Malesi
źródło
4

Wystąpił ten błąd podczas przenoszenia aplikacji Windows na Linuksa. W systemie Windows w nazwach tabel bazy danych wielkość liter nie jest rozróżniana, aw Linuksie wielkość liter jest rozróżniana, prawdopodobnie z powodu różnic w systemie plików. Tak więc w systemie Windows tabela Table1jest taka sama jak table1iw REFERENCESobu table1i Table1działa. W systemie Linux, gdy aplikacja była używana table1zamiast Table1tworzenia struktury bazy danych, zobaczyłem błąd # 150; kiedy poprawiłem wielkość liter w Table1referencjach, zaczęło to działać również na Linuksie. Tak więc, jeśli nic innego nie pomaga, upewnij się, że REFERENCESużywasz poprawnej wielkości liter w nazwie tabeli, gdy używasz Linuksa.

Vitalii
źródło
Tak też było w moim przypadku! Przeniesienie skryptu z wersji mysql bez rozróżniania wielkości liter (OS X) do wersji mysql z rozróżnianiem wielkości liter (Debian).
mircealungu
3

Zmień silniki swoich tabel, tylko innoDB obsługuje klucze obce

Lappies
źródło
3

Jeśli tabela PK jest tworzony w jednej CHARSET a następnie utworzyć tabelę FK w innym CHARSET..then również można dostać ten błąd ... ja też mam ten błąd, ale po zmianie charset do PK charset to dostał wykonany bez błędów

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
źródło
3

Ten błąd może wystąpić, jeśli dwie tabele mają odniesienie, na przykład jedna tabela to Student, a druga to Education, i chcemy, aby tabela Education zawierała odwołanie do klucza obcego tabeli Student. W tym przypadku typ danych kolumny dla obu tabel powinien być taki sam, w przeciwnym razie wygeneruje błąd.

manzarul haque
źródło
3

W większości przypadków problem jest spowodowany różnicą w SILNIKU. Jeśli element nadrzędny jest tworzony przez InnoDB, to tabele, do których się odwołuje, powinny być utworzone przez MyISAM i odwrotnie

Sunil Kumar Mohanty
źródło
3

W moim przypadku. Miałem problemy z silnikiem i kodowaniem, ponieważ mój serwer hostingowy zmienił ustawienia, a moje nowe tabele to MyISAM, ale moje stare tabele to InnoDB. Po prostu się zmieniłem.

Ignacio Hernández
źródło
To było dla mnie dobre, ponieważ modyfikowałem bazę danych, której nie zrobiłem.
FonzTech
3

zwykle niezgodność między kluczem obcym a kluczem podstawowym powoduje błąd: 150.

Klucz obcy muszą mieć ten sam typ danych jako klucz podstawowy . Ponadto, jeśli klucz podstawowy jest unsigned wtedy klucz obcy musi być podpisany .

Rakesh
źródło
3

Miałem ten sam problem. Było to związane z zestawieniem kolumn tabeli i zestawem znaków . Upewnij się, że zestaw znaków i sortowanie muszą być takie same dla obu kolumn w dwóch tabelach. Jeśli chcesz ustawić na to klucz obcy. Przykład - Jeśli umieścisz klucz obcy w kolumnie userID tabeli userImage odwołującej się do kolumny userID w tabeli użytkowników, to sortowanie musi być takie samo, czyli utf8_general_ci i zestaw znaków utf8 dla obu kolumn tabeli. Generalnie podczas tworzenia tabeli mysql pobiera te dwie konfiguracje z ustawień serwera.

Sushilkumar
źródło
Dlaczego wcześniej nie widziałem tego poisty !? Spędziłem godzinę, szukając przyczyny. W moim przypadku był to zestaw znaków. Tabele, do których istnieją odniesienia i które się odwołują, muszą mieć ten sam zestaw znaków.
Sujit Joshi
2

Upewnij się, że zarówno kolumna klucza podstawowego, jak i kolumna, do której się odwołujesz, mają te same typy danych i atrybuty (bez znaku, binarne, wypełnienie zerowe bez znaku itp.).

Basit
źródło
2

Prawdziwym przypadkiem jest sytuacja, w której użyłeś narzędzia MySQL (w moim przypadku Sequel Pro) do zmiany nazwy bazy danych. Następnie utworzono bazę danych o tej samej nazwie.

To zachowało ograniczenia klucza obcego do tej samej nazwy bazy danych, więc baza danych o zmienionej nazwie (np. My_db_renamed) miała ograniczenia klucza obcego w nowo utworzonej bazie danych (my_db)

Nie jestem pewien, czy jest to błąd w Sequel Pro, czy też jakiś przypadek użycia wymaga takiego zachowania, ale kosztowało mnie to większość poranka: /

chim
źródło
2

Miałem ten sam błąd. W moim przypadku przyczyną błędu było to, że miałem w ograniczeniu instrukcję ON DELETE SET NULL, podczas gdy pole, na którym umieściłem ograniczenie w jego definicji, zawierało instrukcję NOT NULL. Zezwolenie na NULL w terenie rozwiązało problem.

Wilbert van Diemen
źródło
2

Spotkałem się z tego rodzaju problemem podczas tworzenia DB z pliku tekstowego.

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 

Właśnie napisałem powyższe wiersze Create.bati uruchomiłem plik bat.

Mój błąd dotyczy kolejności wykonywania w moich plikach sql. Próbowałem stworzyć tabelę z kluczem podstawowym i obcym. Podczas pracy będzie szukać tabeli referencyjnej, ale tabel nie ma. Więc zwróci ten rodzaj błędu.

Jeśli tworzysz tabele z kluczem obcym, sprawdź, czy tabele odniesienia były obecne, czy nie. Sprawdź także nazwy tabel i pól referencyjnych.

Dharani Dharan
źródło
Innymi słowy, próbowałeś utworzyć tabelę z obcym kluczem wskazującym na inną tabelę, która jeszcze nie istniała. Utwórz tabele we właściwej kolejności, aby rozwiązać problem.
Vincent
2

Miałem podobny problem, ale mój wynikał z tego, że dodawałem nowe pole do istniejącej tabeli, która zawierała dane, a nowe pole odwoływało się do innego pola z tabeli nadrzędnej, a także miało definicję NIE NULL i bez żadnych DEFAULT VALUES. - Dowiedziałem się, że coś nie działa, ponieważ

  1. Moje nowe pole musiało automatycznie wypełnić puste pola wartością z tabeli nadrzędnej w każdym rekordzie, zanim można było zastosować ograniczenie. Za każdym razem, gdy ograniczenie jest stosowane, należy pozostawić integralność danych tabeli nienaruszoną. Zaimplementowanie ograniczenia (klucz obcy), ale istniały rekordy bazy danych, które nie miały wartości z tabeli nadrzędnej, oznaczałoby uszkodzenie danych, więc MySQL NIGDY NIE WYKONUJE TWOJEGO OGRANICZENIA

Należy pamiętać, że w normalnych okolicznościach zaplanowanie bazy danych z dużym wyprzedzeniem i zaimplementowanie ograniczeń przed wprowadzeniem danych można by uniknąć tego konkretnego scenariusza

Najłatwiejszym podejściem, aby uniknąć tego problemu

  • Zapisz dane z tabel bazy danych
  • Obetnij dane tabeli (i artefakty tabeli, tj. Indeksy itp.)
  • Zastosuj ograniczenia
  • Importuj swoje dane

Mam nadzieję, że to komuś pomoże

chitwarnold
źródło
1

Może to pomoże? Definicja kolumny klucza podstawowego powinna być dokładnie taka sama, jak kolumna klucza obcego.

Mukus
źródło
1

Upewnij się, że wszystkie tabele obsługują klucz obcy - silnik InnoDB

joksy82
źródło
1

Kolumna tabeli PARENT, do której się odnosisz z tabeli podrzędnej, musi być unikalna. Jeśli tak nie jest, wywołaj błąd nr 150.

Dila Ram Gurung
źródło
prawdopodobnie warto byłoby dodać trochę więcej szczegółów - np. konkretne nazwy kolumn i tabel
Jonathan
1

Miałem podobny problem podczas zrzucania bazy danych Django mysql z pojedynczą tabelą. Udało mi się rozwiązać problem, zrzucając bazę danych do pliku tekstowego, przenosząc daną tabelę na koniec pliku za pomocą emacsa i importując zmodyfikowany plik zrzutu sql do nowej instancji.

HTH Uwe

odkurzacz
źródło
1

Rozwiązałem problem, akceptując zmienną null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
Fahmi
źródło
1

Mam ten sam problem podczas wykonywania serii poleceń MySQL. Mój występuje podczas tworzenia tabeli podczas odwoływania się do klucza obcego do innej tabeli, która nie została jeszcze utworzona. Jest to sekwencja istnienia tabeli przed odwołaniem.

Rozwiązanie: najpierw utwórz tabele nadrzędne, zanim utworzysz tabelę podrzędną z kluczem obcym.

ronIT
źródło
1

Utwórz tabelę bez klucza obcego, a następnie ustaw klucz obcy oddzielnie.

stuckhelper
źródło