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)


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.


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?


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


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.


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.


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


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.


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.


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 :)


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.


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.


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


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;

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.


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


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.


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 .


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.


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.).


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: /


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.


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.


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


1

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


1

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


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.


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


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

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.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.