Kod błędu: 1005. Nie można utworzyć tabeli „…” (errno: 150)

103

Szukałem rozwiązania tego problemu w Internecie i sprawdzałem pytania Stack Overflow, ale żadne z rozwiązań nie działało w moim przypadku.

Chcę utworzyć klucz obcy z tabeli sira_no do metal_kod.

ALTER TABLE sira_no
    ADD CONSTRAINT METAL_KODU FOREIGN KEY(METAL_KODU)
    REFERENCES metal_kod(METAL_KODU)
    ON DELETE SET NULL
    ON UPDATE SET NULL ;

Ten skrypt zwraca:

Error Code: 1005. Can't create table 'ebs.#sql-f48_1a3' (errno: 150)

Próbowałem dodać indeks do wskazanej tabeli:

CREATE INDEX METAL_KODU_INDEX ON metal_kod (METAL_KODU);

Sprawdziłem METAL_KODU na obu tabelach (zestaw znaków i sortowanie), ale nie mogłem znaleźć rozwiązania tego problemu. Jak mogę rozwiązać ten problem?

Oto tabela metal_kod:

METAL_KODU    varchar(4)    NO    PRI
DURUM    bit(1)    NO
METAL_ISMI    varchar(30)    NO
AYAR_YOGUNLUK    smallint(6)    YES        100
lamostreta
źródło
Czy możesz pokazać schemat metal_kodtabeli ... do którego pola w tej tabeli powinien odnosić się klucz obcy?
Manse

Odpowiedzi:

271

Kod błędu: 1005 - w kodzie znajduje się nieprawidłowe odwołanie do klucza podstawowego

Zwykle jest to spowodowane odwołaniem do pola klucza obcego, które nie istnieje. Możliwe, że popełniono błąd literowy lub sprawdź, czy powinien być taki sam, lub niezgodność typu pola. Pola połączone z kluczem obcym muszą dokładnie odpowiadać definicjom.

Niektóre znane przyczyny to:

  1. Typ i / lub rozmiar dwóch pól kluczowych nie pasują dokładnie. Na przykład, jeśli jedno jest INT(10)kluczowym polem, musi być INT(10)również, a nie INT(11)lub TINYINT. Możesz chcieć potwierdzić rozmiar pola za pomocą, SHOW CREATE TABLEponieważ przeglądarka zapytań czasami wyświetla wizualnie tylko INTEGERdla obu INT(10)i INT(11). Powinieneś także sprawdzić, czy jeden nie jest, SIGNEDa drugi jest UNSIGNED. Obaj muszą być dokładnie tacy sami.
  2. Jedno z pól klucza, do którego próbujesz się odwołać, nie ma indeksu i / lub nie jest kluczem podstawowym. Jeśli jedno z pól w relacji nie jest kluczem podstawowym, musisz utworzyć indeks dla tego pola.
  3. Nazwa klucza obcego jest duplikatem już istniejącego klucza. Sprawdź, czy nazwa Twojego klucza obcego jest unikatowa w Twojej bazie danych. Po prostu dodaj kilka losowych znaków na końcu nazwy klucza, aby to sprawdzić.
  4. Jeden lub oba stoły to MyISAMstół. Aby używać kluczy obcych, obie tabele muszą być InnoDB. (Właściwie, jeśli obie tabele są MyISAM, nie otrzymasz komunikatu o błędzie - po prostu nie utworzy klucza). W przeglądarce zapytań możesz określić typ tabeli.
  5. Określono kaskadę ON DELETE SET NULL, ale odpowiednie pole klucza jest ustawione na NOT NULL. Możesz to naprawić, zmieniając kaskadę lub ustawiając pole, aby zezwolić na NULLwartości.
  6. Upewnij się, że opcje Charset i Collate są takie same zarówno na poziomie tabeli, jak i na poziomie poszczególnych pól dla kolumn kluczowych.
  7. Masz domyślną wartość (czyli default = 0) w kolumnie klucza obcego
  8. Jedno z pól w relacji jest częścią klucza kombinowanego (złożonego) i nie ma własnego indywidualnego indeksu. Mimo że pole ma indeks jako część klucza złożonego, należy utworzyć oddzielny indeks tylko dla tego pola klucza, aby użyć go w ograniczeniu.
  9. Wystąpił błąd składni w ALTERinstrukcji lub błędnie wpisałeś jedną z nazw pól w relacji
  10. Nazwa twojego klucza obcego przekracza maksymalną długość 64 znaków.

Aby uzyskać więcej informacji, zobacz: Numer błędu MySQL 1005 Nie można utworzyć tabeli

Peter Mortensen
źródło
4
problem polegał na tym, że zestawy znaków klucza obcego nie pasowały. Dziękuję za odpowiedź.
lamostreta
4
SHOW ENGINE INNODB STATUSjak wspomniano w tym pytaniu pomogło mi zdiagnozować mój konkretny problem (PEBCAK, w moim przypadku ...)
Hobo
1
cholera, nawet to jest klucz główny. Musisz utworzyć indywidualny indeks dla tego klucza. dzięki temu rozwiązałem mój problem.
RSB
3
# 4 był moim problemem - jedną z tabel był MyISAM, a skrypt próbował utworzyć tabelę InnoDB. Napotkałem ten problem, gdy próbowałem wdrożyć stary system, na którym początkowo działał MySQL 5.0 lub podobna wersja, gdzie domyślnym silnikiem pamięci był MyISAM, a skrypty działały poprawnie. Moje obecne środowisko to 5.5, a domyślna pamięć masowa to InnoDB. Dodanie set names 'utf8', storage_engine=MYISAM;na początku skryptu rozwiązało problem za mnie. Dziękuję @ user319198 i @Stefano za wyczerpującą odpowiedź! : o)
Boris Chervenkov
1
W moim brakowało atrybutu „bez znaku”, jak wspomniano w punkcie 1, dzięki!
helvete
11

Może się to również zdarzyć podczas eksportowania bazy danych z jednego serwera na inny, a tabele są domyślnie wymienione w kolejności alfabetycznej.
Tak więc twoja pierwsza tabela może mieć klucz obcy innej tabeli, która nie została jeszcze utworzona. W takich przypadkach wyłącz Foreign_key_checks i utwórz bazę danych.

Po prostu dodaj do swojego skryptu:

SET FOREIGN_KEY_CHECKS=0;

i będzie działać.

happyhardik
źródło
4

Bardzo często dzieje się tak, gdy klucz obcy i klucz referencyjny nie mają tego samego typu lub tej samej długości.

zahid9i
źródło
4

Czasami jest to spowodowane usunięciem tabeli głównej (być może przez wyłączenie sprawdzania klucza obcego), ale klucz obcy CONSTRAINT nadal istnieje w innych tabelach. W moim przypadku upuściłem stół i próbowałem go odtworzyć, ale rzucał mi ten sam błąd.

Spróbuj więc usunąć wszystkie klucze obce CONSTRAINT ze wszystkich tabel, jeśli takie istnieją, a następnie zaktualizuj lub utwórz tabelę.

rajug
źródło
2

Miałem podobny błąd. Problem dotyczył tego, że tabela podrzędna i nadrzędna nie miały tego samego zestawu znaków i sortowania. Można to naprawić, dołączając ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

CREATE TABLE IF NOT EXISTS `country` (`id` INT(11) NOT NULL AUTO_INCREMENT,...) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

... w instrukcji SQL oznacza, że ​​brakuje jakiegoś kodu.

user2258168
źródło
2

Klucz obcy musi mieć dokładnie taki sam typ jak klucz podstawowy, do którego się odwołuje. Na przykład ma typ „INT UNSIGNED NOT NULL”, klucz foreing również musi mieć wartość „INT UNSIGNED NOT NULL”

CREATE TABLE employees(
id_empl INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id)
);
CREATE TABLE offices(
id_office INT UNSIGNED NOT NULL AUTO_INCREMENT,
id_empl INT UNSIGNED NOT NULL,
PRIMARY KEY(id),
CONSTRAINT `constraint1` FOREIGN KEY (`id_empl`) REFERENCES `employees` (`id_empl`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='my offices';
Yaina Villafañes
źródło
brak podpisu był dla mnie problemem. Dzięki!
Gabo
2

Kod błędu: 1005

Miałem podobny problem, więc oto kilka rzeczy, które wypróbowałem (nie w dowolnej kolejności, z wyjątkiem rozwiązania :))

  1. Zmieniono nazwy kluczy obcych (nie zadziałało)
  2. Zmniejszono długość klucza obcego
  3. Zweryfikowano typy danych (cholera nic złego)
  4. Sprawdź indeksy
  5. Sprawdź zestawienia (wszystko w porządku, znowu cholera)
  6. Obcięty stół, bezużyteczny
  7. Usunięto tabelę i utworzono ponownie
  8. Próbowałem sprawdzić, czy tworzone jest odwołanie cykliczne - wszystko w porządku
  9. W końcu zobaczyłem, że mam otwartych dwóch edytorów. Jeden w PhpStorm (JetBrains) i drugi w Środowisku roboczym MySQL. Wygląda na to, że PhpStorm / MySQL Workbench tworzy pewnego rodzaju blokadę edycji.

    Zamknąłem PhpStorm tylko po to, aby sprawdzić, czy istnieje blokowanie (mogło być na odwrót). To rozwiązało mój problem.

Rajiv Nair
źródło
2

Otrzymałem ten sam komunikat o błędzie. W końcu zorientowałem się, że błędnie wpisałem nazwę tabeli w poleceniu:

ALTER TABLE `users` ADD FOREIGN KEY (country_id) REFERENCES country (id);

przeciw

ALTER TABLE `users` ADD FOREIGN KEY (country_id) REFERENCES countries (id);

Zastanawiam się, dlaczego MySQL nie może powiedzieć, że taka tabela nie istnieje ...

Csongor Halmai
źródło
1

Właśnie wspomniano o MyISAM. Po prostu spróbuj dodać ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 2; na końcu instrukcji, zakładając, że inne tabele zostały utworzone za pomocą MyISAM.

CREATE TABLE IF NOT EXISTS `tablename` (
  `key` bigint(20) NOT NULL AUTO_INCREMENT,
  FOREIGN KEY `key` (`key`) REFERENCES `othertable`(`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Damir Olejar
źródło
1

W moim przypadku stało się tak, gdy jeden stół to InnoB, a drugi to MyISAM. Zmiana silnika jednej tabeli, poprzez MySQL Workbench, rozwiązuje za mnie.

rkawano
źródło
1

Stało się tak w moim przypadku, ponieważ nazwa tabeli, do której się odwołujemy w deklaracji ograniczenia, nie była poprawna (zapomniałem dużej litery w nazwie tabeli):

ALTER TABLE `Window` ADD CONSTRAINT `Windows_ibfk_1` FOREIGN KEY (`WallId`) REFERENCES `Wall` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Abdellah Alaoui
źródło
1

sprawdź, czy obie tabele mają ten sam schemat InnoDB MyISAM. Zrobiłem je wszystkie w moim przypadku InnoDB i działałem

Brian Sanchez
źródło
1

Mój problem nie został wymieniony, to było coś tak głupiego ..... Tabela, która ma FKas PK była złożeniem, PKktóre zostało zadeklarowane w następujący sposób: klucz podstawowy ( CNPJ, CEP) Chciałem, aby pole CEP było FKw innej tabeli i byłem utknąłem w tym błędzie, morał tej historii właśnie odwrócił powyższy kod dla klucza podstawowego ( CEP, CNPJ) i zadziałało. Daj napiwek swoim znajomym.

fagner willys
źródło