2013-08-22 16 views
9

Sto cercando di creare una tabella con una colonna varchar come chiave esterna ma MySql mi dà un errore durante la creazione della tabella. La mia domanda è come questo:Tabella MySQL con una colonna varchar come chiave esterna

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; 

ed ottengo questo errore:

[Err] 1215 - Cannot add foreign key constraint 

Sto usando MySQL 5.6.12. Come posso riscrivere la mia query per risolverlo?

risposta

16

È possibile avere solo una chiave esterna che fa riferimento a un campo univoco. Modifica la tabella di network_classes modo che il campo categoria è unica, come qui di seguito

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; 

Si dovrebbe quindi essere in grado di aggiungere la chiave esterna che si desidera

0

in

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

si è utilizzato network_classess invece di network_classes (come nel vostro script creare tabella), in modo che non esista tavolo.

EDIT

Nome del tuo vincolo è lo stesso di quelli chiave (networks_fk1) cambia.

Ho letto meglio il tuo DDL.

La tua tabella network_classes ha un ID di chiave primaria, quindi è corretto mettere come chiave esterna un campo per collegare il tuo campo ID, il campo categoria non deve apparire nella tua rete di tabelle, ma penso che devi mettere fk_network_class (come int) collegato a id (di network_classes)

+0

ho corretto, ma hanno ancora lo stesso problema –

+0

tuo network_classess è vuoto ? Un'altra cosa, se si definisce una chiave primaria composta, la chiave esterna deve essere uguale (non ha alcun impatto sul proprio errore) –

+0

sì, lo è. puoi per favore eseguire la query dalla tua parte? Sto cercando una soluzione pratica piuttosto che l'immaginazione teorica. –

5

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

Perché 2 colonne varchar con le stesse dimensioni non corrispondono nel tipo? E ovviamente la risposta è scontata. Risulta che nella nuova tabella la colonna era UTF-8 invece di ASCII come nella tabella di riferimento. Cambiato in ASCII e fatto.

+0

Entrambi usano lo stesso tipo (tipo predefinito). Come lo dici!!?? –

+0

vale anche la pena menzionare, assicurati che siano entrambi i tavoli InnoDB –

1

L'obiettivo di un vincolo FOREIGN KEY deve essere indicizzato. Di solito, è un PRIMARY KEY quindi non è un problema, ma nel tuo caso non lo è (anche se fa parte di una chiave composta, non è sufficiente)

Creare un indice sul tuo network_classes. category campo:

CREATE INDEX category_idx ON network_classes(category); 

quindi ricreare la vostra tavola networks.

+0

Grazie mille Jeremy. Ho creato l'indice e ha risolto. –

Problemi correlati