2013-03-11 9 views
5

Ich habe eine Tabelle in MySQL InnoDB so erstellt:MySQL - nicht fremd add key

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 

Als nächstes habe ich versucht, eine Tabelle mit einer solchen Aussage Hinzufügen (keine Fremdschlüssel hinzugefügt, während der Erstellung der Tabelle als Problem hatte mit dass):

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 

Mit Tabellen erstellt, muss ich Fremdschlüssel auf 'from' und 'to' Felder hinzufügen Referenzierung 'users'.'id' Feld schließlich zu:

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) 

Der Fehler, den ich bekommen ist:

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

Aber ‚Benutzer‘ Tabelle einen PRIMARY Index auf 'id' hat ...

Auch einen kleinen Schritt zu machen versucht und Fremdschlüssel hinzufügen nur für 'from' Feld :

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

Der Fehler ist etwas anders:

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

Die Typen der Felder sind identisch (bigint(20) NOT NULL), da sie als Ursache für das Problem in anderen StackOverflow-Threads vorgeschlagen wurden. Meine Tabellen sind nicht partitioniert (das Handbuch von MySQL gibt dies als Einschränkung für das Vorhandensein von Fremdschlüsseleinschränkungen in InnoDB an). Die 'messages' Tabelle speichert derzeit keine Zeilen, daher können gespeicherte Daten in keiner Weise das Problem sein. Ich stecke fest, bitte hilf mir.

+1

+1 Schön, wirklich 'CREATE TABLE' zu sehen, um mit ihnen zu spielen :) –

Antwort

0

REFERENCES Benutzer ( id , id )

Sie versuchen, einen ungültigen Fremdschlüssel (id, id) zu erstellen. Die Spalten, die in einem zusammengesetzten Index enthalten sind (einer mit mehr als einer Spalte), können nicht dieselbe Spalte sein, die wiederholt wird. Zumindest habe ich das nie gesehen.

Erstellen Sie zwei separate Fremdschlüssel, einen für FROM und den anderen für TO, wobei jeder auf Benutzer zurückweist.

+0

Ja, ich dachte über den Unterschied zwischen diesen beiden Ansätzen nach. Getrennte Fremdschlüssel sind das, was ich wirklich brauche. Vielen Dank. –

14

Wenn Sie über die entsprechenden Berechtigungen verfügen, können Sie diese Abfrage ausführen:

SHOW ENGINE innodb STATUS 

... was Sie sagen (unter einem anderen info) die genauen Details des Fehlers:

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

Auf übergeordneten Datensatz löschen, können Sie nicht untergeordneten Datensatz NULL machen, weil die Spalten NOT NULL:

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

Bearbeiten: Darüber hinaus kann ich den Zweck eines einzelnen zusammengesetzten Schlüssels nicht sehen. Ich denke du willst stattdessen zwei einzelne Schlüssel.

+1

StackOverflow Community hilfreich und schnell wie immer :-). Ich kann jetzt meinen Fehler sehen, danke! –

+1

Irgendwelche Ideen, wenn 'SHOW ENGINE innodb STATUS' nicht den neuesten Fremdschlüsselfehler anzeigt? – antonagestam

+0

Danke U! +1 Alavaro. Du rettest mich vor einer zweiten Nacht! Danke noch einmal. –

0

Wie wir gesehen haben,

Sie können nicht SET NULL in untergeordneten Datensätzen definieren, wenn das Kind Spalten from und to nicht null sind.Wenn Sie versuchen, die Fremdschlüssel mit den folgenden zwei Anweisungen zu erstellen, sollten Sie die Fremdschlüssel in der Tabelle messages haben.

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

und

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

Hoffnung diese Aussagen Ihnen helfen.