2013-08-22 3 views
9

Ich versuche, eine Tabelle mit einer Varchar-Spalte als Fremdschlüssel zu erstellen, aber MySql gibt mir einen Fehler beim Erstellen der Tabelle. Meine Frage ist wie folgt:MySQL-Tabelle mit einer Varchar-Spalte als Fremdschlüssel

CREATE TABLE network_classes (
    id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT, 
    category VARCHAR(80) NOT NULL, 
    PRIMARY KEY(id), 
    KEY `key_1` (`id`,`category`) 
) 
ENGINE=InnoDB; 


CREATE TABLE networks (
    id TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT, 
    name VARCHAR(100) NOT NULL, 
    category VARCHAR(80) NOT NULL, 
    director_id TINYINT(3) UNSIGNED NULL, 
    director_name VARCHAR(100) NULL, 
    description VARCHAR(1000) NULL, 
    last_modified TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, 
    user_id SMALLINT UNSIGNED NULL, 
    PRIMARY KEY(id), 
    KEY `networks_fk1` (`category`), 
    CONSTRAINT `networks_fk1` FOREIGN KEY (`category`) REFERENCES `network_classes` (`category`) ON DELETE NO ACTION, 
    INDEX networks_index2471(name), 
    INDEX networks_index2472(director_id, director_name) 
) 
ENGINE=InnoDB; 

und ich bekomme diese Fehlermeldung:

[Err] 1215 - Cannot add foreign key constraint 

Ich bin mit MySQL 5.6.12. Wie kann ich meine Anfrage umschreiben, um sie zu beheben?

Antwort

16

Sie können nur einen Fremdschlüssel verwenden, der auf ein eindeutiges Feld verweist. Ändern Sie bitte Ihre network_classes Tabelle, so dass das Kategoriefeld eindeutig zuzuordnen sind, wie unter

CREATE TABLE network_classes (
    id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT, 
    category VARCHAR(80) NOT NULL, 
    PRIMARY KEY(id), 
    UNIQUE KEY `category_UNIQUE` (`category`), 
    KEY `key_1` (`id`,`category`) 
) 
ENGINE=InnoDB; 


CREATE TABLE networks (
    id TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT, 
    name VARCHAR(100) NOT NULL, 
    category VARCHAR(80) NOT NULL, 
    director_id TINYINT(3) UNSIGNED NULL, 
    director_name VARCHAR(100) NULL, 
    description VARCHAR(1000) NULL, 
    last_modified TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, 
    user_id SMALLINT UNSIGNED NULL, 
    PRIMARY KEY(id), 
    KEY `networks_fk1` (`category`), 
    CONSTRAINT `networks_fk1` FOREIGN KEY (`category`) REFERENCES `network_classes` (`category`) ON DELETE NO ACTION, 
    INDEX networks_index2471(name), 
    INDEX networks_index2472(director_id, director_name) 
) 
ENGINE=InnoDB; 

Sie sollten dann in der Lage sein, den Fremdschlüssel hinzufügen Sie

0

in

CONSTRAINT `networks_fk1` FOREIGN KEY (`category`) 
REFERENCES `network_classess` (`category`) ON DELETE NO ACTION, 

haben Sie network_classess statt network_classes verwendet (wie in der Tabelle Skript), so dass Tabelle nicht vorhanden ist.

EDIT

Name des Constraint ist die gleiche Schlüssel (networks_fk1) ändern diejenigen.

Ich lese besser Ihre DDL.

Ihre Tabelle network_classes hat eine Primärschlüssel-ID, so ist korrekt als Fremdschlüssel ein Feld zum Verlinken Ihres ID-Felds, das Kategoriefeld darf nicht in Ihrem Tabellennetzwerk erscheinen, aber ich denke, Sie müssen fk_network_class (als int) verbunden mit id (von network_classes)

+0

ich es korrigiert, aber immer noch das gleiche Problem –

+0

Ihr network_classess ist leer ? Eine andere Sache, wenn Sie einen zusammengesetzten Primärschlüssel definieren, sollte der Fremdschlüssel gleich sein (es hat keinen Einfluss auf Ihren Fehler) –

+0

ja, ist es. Können Sie bitte die Abfrage auf Ihrer Seite ausführen? Ich suche eher nach einer praktischen Lösung als nach theoretischen Vorstellungen. –

5

column types in the table and the referenced table do not match for constraint

Warum 2 varchar Spalten mit gleicher Größe nicht in Typ übereinstimmen? Und natürlich ist die Antwort offensichtlich Collation. Es stellte sich heraus, dass in der neuen Tabelle die Spalte UTF-8 anstelle von ASCII war, wie in der referenzierten Tabelle. In ascii geändert und fertig.

+0

Beide verwenden den gleichen Typ (Standardtyp). Wie sagt man das!!?? –

+0

auch erwähnenswert, stellen Sie sicher, dass sie beide InnoDB Tabellen sind –

1

Das Ziel einer Constraint FOREIGN KEY muss indiziert werden. Normalerweise ist es ein PRIMARY KEY, also ist das kein Problem, aber in Ihrem Fall ist es nicht (obwohl es Teil eines zusammengesetzten Schlüssels ist, ist das nicht genug)

Erstellen Sie einen Index für Ihre. category Feld:

CREATE INDEX category_idx ON network_classes(category); 

erstellen Sie dann Ihre networks Tisch.

+0

Vielen Dank Jeremy. Ich habe den Index erstellt und ihn gelöst. –