2013-03-11 14 views
5

Mam tabeli w MySQL InnoDB stworzony tak:MySQL - nie można dodać klucz obcy

CREATE TABLE `users` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `type` enum('MANUAL','FACEBOOK') NOT NULL DEFAULT 'MANUAL', 
    `role` enum('COOK','HOST','ALL') NOT NULL DEFAULT 'ALL', 
    `about_me` varchar(1000) DEFAULT NULL, 
    `food_preferences` varchar(1000) DEFAULT NULL, 
    `cooking_experience` varchar(1000) DEFAULT NULL, 
    `with_friend` bit(1) DEFAULT b'0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 

Następny Próbowałem dodając tabelę z takiego oświadczenia (bez kluczy obcych dodawane podczas tworzenia tabeli, jak miał problemy z że):

CREATE TABLE `messages` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `from` bigint(20) NOT NULL, 
    `to` bigint(20) NOT NULL, 
    `content` varchar(10000) NOT NULL, 
    `timestamp_sent` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `timestamp_read` timestamp NULL DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

uwzględniając tabele tworzone, muszę wreszcie dodać kluczy obcych na 'from' i 'to' pól odwołujących 'users'.'id' murawę:

ALTER TABLE `messages` 
    ADD CONSTRAINT `messages_users_fk` 
    FOREIGN KEY (`from` , `to`) 
    REFERENCES `users` (`id` , `id`) 
    ON DELETE SET NULL 
    ON UPDATE CASCADE 
, ADD INDEX `messages_users_fk_idx` (`from` ASC, `to` ASC) 

Błąd pojawia się:

ERROR: Error 1822: Failed to add the foreign key constraint. Missing index for constraint 'messages_users_fk' in the referenced table 'users'.

Ale stół „użytkownicy” ma PRIMARY indeks 'id' ...

również próbował zrobić mniejszy krok i dodać klucz obcy dla 'from' dziedzinie :

ALTER TABLE `messages` 
    ADD CONSTRAINT `messages_users_fk` 
    FOREIGN KEY (`from`) 
    REFERENCES `users` (`id`) 
    ON DELETE SET NULL 
    ON UPDATE CASCADE 
, ADD INDEX `messages_users_fk_idx` (`from` ASC) ; 

błąd jest nieco inna:

ERROR: Error 1825: Failed to add the foreign key constraint on table 'messages'. Incorrect options in FOREIGN KEY constraint 'cook4food/messages_users_fk'.

Typy pól są takie same (bigint(20) NOT NULL), co sugerowano jako przyczynę problemu w innych wątkach StackOverflow. Moje tabele nie są partycjonowane (podręcznik MySQL określa to jako ograniczenie posiadania ograniczeń klucza obcego w InnoDB). Tabela 'messages' nie przechowuje obecnie żadnych wierszy, więc dane przechowywane w żaden sposób nie mogą być problemem. Utknąłem, proszę o pomoc.

+1

+1 Piękny, aby zobaczyć aktualne instrukcje "STWÓRZ TABELĘ", aby się z nimi bawić :) –

Odpowiedz

0

REFERENCES użytkowników ( id , id )

Próbujesz utworzyć niepoprawny klucz obcy (ID, ID). Kolumny biorące udział w indeksie złożonym (z których jeden dotyczy więcej niż jednej kolumny) nie mogą być tą samą kolumną, powtarzaną. Przynajmniej nigdy tego nie widziałem.

Utwórz dwa oddzielne klucze obce, jeden dla FROM i drugi dla TO, każdy z powrotem skierowany do użytkowników.

+0

Tak, myślałem o różnicy między tymi dwoma podejściami. Oddzielne klucze obce są tym, czego naprawdę potrzebuję. Dzięki. –

14

Jeśli masz odpowiednie uprawnienia, można wydać to zapytanie:

SHOW ENGINE innodb STATUS 

... co powie (wśród innej informacji) dokładne szczegóły błędu:

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
130311 13:30:06 Error in foreign key constraint of table test/#sql-71c_6: 

    FOREIGN KEY (`from` , `to`) 
    REFERENCES `users` (`id` , `id`) 
    ON DELETE SET NULL 
    ON UPDATE CASCADE 
, ADD INDEX `messages_users_fk_idx` (`from` ASC, `to` ASC): 
You have defined a SET NULL condition though some of the 
columns are defined as NOT NULL. 

Na usunięciem rekordu rodzic, nie można zrobić rekord dziecko NULL, ponieważ kolumny są NOT NULL:

`from` bigint(20) NOT NULL, 
    `to` bigint(20) NOT NULL, 

Edytuj: Ponadto nie widzę celu pojedynczego klucza złożonego. Myślę, że chcesz zamiast tego dwa klucze.

+1

Społeczność StackOverflow pomocna i szybka jak zawsze :-). Teraz widzę mój błąd, dziękuję! –

+1

Wszelkie pomysły, jeśli "SHOW ENGINE innodb STATUS" nie pokazuje NAJNOWSZEJ BŁĘDY KLUCZA ZAGRANICZNEGO? – antonagestam

+0

Dziękuję U! +1 Alavaro. Ratujesz mnie od drugiej nocy! Dzięki jeszcze raz. –

0

Jak widzieliśmy,

Nie można zdefiniować SET NULL w ewidencji dzieci, gdy dziecko from kolumny i to nie są nieważne.

Jeśli więc spróbujesz utworzyć klucze obce z następującymi 2 instrukcjami, powinieneś mieć klucze obce w tabeli messages.

1>

ALTER TABLE `messages` ADD CONSTRAINT `messages_users_from_fk` FOREIGN KEY (`from`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX `messages_users_fk_idx` (`from` ASC) ; 

i

2>

ALTER TABLE `messages` ADD CONSTRAINT `messages_users_to_fk` FOREIGN KEY (`to`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX `messages_users_fk_to_idx` (`to` ASC) ; 

nadzieję, że te wypowiedzi pomóc.