2009-07-05 10 views
18

Stworzyłem model z MySQL Workbench i teraz próbuję zainstalować go na serwerze mysql.MySQL: Tworzenie tabeli z błędem FK (errno 150)

Korzystanie z Plik> Eksportuj> Przekaż inżynier SQL CREATE Script ... Wydaje dla mnie ładny, duży plik, ze wszystkimi ustawieniami, o które pytam. Przełączam się na MySQL GUI Tools (w szczególności przeglądarkę zapytań) i ładuję ten skrypt (zauważ, że przechodzę z jednego oficjalnego narzędzia MySQL na inny). Jednak, gdy próbuję faktycznie wykonać ten plik, pojawia się ten sam błąd w kółko

SQLSTATE[HY000]: General error: 1005 Can't create table './srs_dev/location.frm' (errno: 150)

„OK”, mówię sobie, że coś jest nie tak z tabeli lokalizacji. Więc sprawdzam definicję w pliku wyjściowym.

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 

-- ----------------------------------------------------- 
-- Table `state` 
-- ----------------------------------------------------- 
DROP TABLE IF EXISTS `state` ; 

CREATE TABLE IF NOT EXISTS `state` (
    `state_id` INT NOT NULL AUTO_INCREMENT , 
    `iso_3166_2_code` VARCHAR(2) NOT NULL , 
    `name` VARCHAR(60) NOT NULL , 
    PRIMARY KEY (`state_id`)) 
ENGINE = InnoDB; 

-- ----------------------------------------------------- 
-- Table `brand` 
-- ----------------------------------------------------- 
DROP TABLE IF EXISTS `brand` ; 

CREATE TABLE IF NOT EXISTS `brand` (
    `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
    `name` VARCHAR(45) NOT NULL , 
    `domain` VARCHAR(45) NOT NULL , 
    `manager_name` VARCHAR(100) NULL , 
    `manager_email` VARCHAR(255) NULL , 
    PRIMARY KEY (`brand_id`)) 
ENGINE = InnoDB; 

-- ----------------------------------------------------- 
-- Table `location` 
-- ----------------------------------------------------- 
DROP TABLE IF EXISTS `location` ; 

CREATE TABLE IF NOT EXISTS `location` (
    `location_id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
    `name` VARCHAR(255) NOT NULL , 
    `address_line_1` VARCHAR(255) NULL , 
    `address_line_2` VARCHAR(255) NULL , 
    `city` VARCHAR(100) NULL , 
    `state_id` TINYINT UNSIGNED NULL DEFAULT NULL , 
    `postal_code` VARCHAR(10) NULL , 
    `phone_number` VARCHAR(20) NULL , 
    `fax_number` VARCHAR(20) NULL , 
    `lat` DECIMAL(9,6) NOT NULL , 
    `lng` DECIMAL(9,6) NOT NULL , 
    `contact_url` VARCHAR(255) NULL , 
    `brand_id` TINYINT UNSIGNED NOT NULL , 
    `summer_hours` VARCHAR(255) NULL , 
    `winter_hours` VARCHAR(255) NULL , 
    `after_hours_emergency` VARCHAR(255) NULL , 
    `image_file_name` VARCHAR(100) NULL , 
    `manager_name` VARCHAR(100) NULL , 
    `manager_email` VARCHAR(255) NULL , 
    `created_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , 
    PRIMARY KEY (`location_id`) , 
    CONSTRAINT `fk_location_state` 
    FOREIGN KEY (`state_id`) 
    REFERENCES `state` (`state_id`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_location_brand` 
    FOREIGN KEY (`brand_id`) 
    REFERENCES `brand` (`brand_id`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 

CREATE INDEX `fk_location_state` ON `location` (`state_id` ASC) ; 

CREATE INDEX `fk_location_brand` ON `location` (`brand_id` ASC) ; 

CREATE INDEX `idx_lat` ON `location` (`lat` ASC) ; 

CREATE INDEX `idx_lng` ON `location` (`lng` ASC) ; 

Wygląda dobrze. Przypuszczam, że może coś jest nie tak z Query Browser, więc mogę umieścić ten plik na serwerze i spróbuj załadować go w ten sposób

] mysql -u admin -p -D dbname < path/to/create_file.sql 

I uzyskać ten sam błąd. Tak więc zaczynam od Google'a ten problem i znajduję wszystkie rodzaje kont, które mówią o błędzie w tabelach w stylu InnoDB, które zawiodły w przypadku kluczy obcych, a poprawka polega na dodaniu "SET FOREIGN_KEY_CHECKS = 0;" do skryptu SQL. Jak widać, jest to już część pliku, który MySQL Workbench wypluł.

Moje pytanie brzmi: dlaczego to nie działa, kiedy robię to, co myślę, że powinienem robić?

Version Info:

  • MySQL: 5.0.45

  • GUI Tools: 1.2.17
  • Workbench: 5.0.30
+1

Chociaż nie jest tak w przypadku SQL, ten sam błąd jest również spowodowany brakiem unikalnych nazw kluczy obcych między tabelami. –

Odpowiedz

40

typ pola w sposób klucz obcy musi być taki sam, jak typ kolumny, do której się odnoszą. Masz następujący (Wycinanie):

CREATE TABLE IF NOT EXISTS `state` (
    `state_id` INT NOT NULL AUTO_INCREMENT , 
... 
CREATE TABLE IF NOT EXISTS `brand` (
    `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT , 
... 
CREATE TABLE IF NOT EXISTS `location` (
... 
    `state_id` TINYINT UNSIGNED NULL DEFAULT NULL , 
... 
    `brand_id` TINYINT UNSIGNED NOT NULL , 

więc starasz się odnieść do INT pól (w tabelach state i brand) z TINYINT pól w tabeli location. Myślę, że to błąd, na który narzeka. Nie wiesz, jak to się stało, lub dlaczego wyzerowanie FOREIGN_KEY_CHECKS nie powstrzymuje MySQL przed diagnozowaniem błędu, ale co się stanie, jeśli naprawisz niedopasowanie tego typu?

+2

OK, um ... haha. Wow, to zawstydzające. Byłem tak zajęty szukaniem czegoś złego w rzeczywistym związku, że nie sprawdzałem samych kolumn. Dzięki za drugą parę oczu! –

+3

Wow! Stało się to również przy mieszaniu "INT" i "INT UNSIGNED". Tak, to była moja wina; ale MySQL Workbench wymaga ostrzeżenia o tym! – Mauro

+1

Dziękuję bardzo! Po prostu musiałem dodać UNSIGNED do wszystkich kluczy obcych INT. –

9

Dla innych patrząc na tego wątku, istnieje wiele powodów, które można dostać ten błąd:

Zobacz poniższy link do pełnej listy dla errno 150, errno 121 i innych kluczowych MySQL obce błędy:

MySQL Foreign Key Errors and Errno 150

+1

Tak, dziękuję! BTW, uwielbiam komiks xkcd. Potrafię nawiązać w wielkim stylu! Pozdrawiam. – SecondSun24

+1

To była odpowiedź, której potrzebowałem. Moim problemem był MyISAM zamiast InnoDB. – Ryan

-2

Miałem ten sam problem. Jakoś nie zauważyłem, aby ustawić wartość auto_increment na identyfikator tabeli. Może to pomaga komuś.

+5

'AUTO_INCREMENT' lub nie, nie ma wpływu na ważność klucza obcego. –

0

Właśnie sprawdziłem odpowiedź @juacala. Ale mi nie pomogło. Oto wiadomość, którą wysłałem @ELIACOM, gdy znalazłem źródło problemu.:

I was reading this great source of solutions, but my issue is not adressed. I was trying to add an FK in a INNODB table pointing to a PK in a MyISAM. After setting the MyIsam to INNODB it worked. I checked your whole list before realizing that. Cheers.

+0

To tam, ale w niektórych wersjach dodatek klucza obcego po cichu zawiedzie. To jest # 2 na liście pod "innymi błędami klucza obcego" – juacala