2013-03-11 34 views
5

Ho una tabella in MySQL InnoDB creato così:MySQL - non può aggiungere estera chiave

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 

Poi ho provato ad aggiungere una tabella con una tale affermazione (non le chiavi esterne aggiunto durante la creazione della tabella come avuto problemi con che):

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 

Avendo tabelle create, ho bisogno di aggiungere, infine, chiavi esterne su 'from' e 'to' campi che fanno riferimento 'users'.'id' campo:

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) 

L'errore che ottengo è:

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

Ma tabella 'utenti' ha un indice PRIMARY su 'id' ...

cercato anche di fare un passo più piccolo e aggiungere chiave esterna solo per 'from' campo :

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

L'errore è leggermente diverso:

01.235.164,106174 millions

I tipi di campi sono gli stessi (bigint(20) NOT NULL) come è stato suggerito come causa del problema in altri thread StackOverflow. Le mie tabelle non sono partizionate (il manuale MySQL lo afferma come una limitazione per avere vincoli di chiave esterna in InnoDB). La tabella 'messages' non memorizza alcuna riga al momento, quindi i dati memorizzati non possono essere il problema in alcun modo. Sono bloccato, per favore aiuto.

+1

+1 Bello vedere le istruzioni effettive 'CREATE TABLE' per giocare con loro :) –

risposta

0

REFERENCES utenti ( id , id )

Si sta tentando di creare un chiave esterna non valida (id, id). Le colonne coinvolte in un indice composito (una che coinvolge più di una colonna) non possono essere la stessa colonna, ripetuta. Almeno non l'ho mai visto.

Creare due chiavi esterne separate, una per FROM e l'altra per TO, ciascuna rivolta verso gli utenti.

+0

Sì, stavo pensando alla differenza tra questi due approcci. Le chiavi esterne separate sono ciò di cui ho veramente bisogno. Grazie. –

14

Se si dispone dei privilegi appropriati, è possibile emettere questa query:

SHOW ENGINE innodb STATUS 

... che vi dirà (fra qualche altra info) i dettagli esatti dell'errore:

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

il record principale l'eliminazione, non è possibile effettuare record figlio NULL perché le colonne sono NOT NULL:

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

Modifica: Inoltre, non riesco a vedere lo scopo di una singola chiave composita. Penso che tu voglia due chiavi singole invece.

+1

La community di StackOverflow è utile e veloce come sempre :-). Posso vedere il mio errore ora, grazie! –

+1

Qualche idea se 'SHOW ENGINE innodb STATUS' non mostra ULTIMO ERRORE CHIAVE STRANIERI? – antonagestam

+0

Grazie U! +1 Alavaro. Mi salvi da una seconda notte! Grazie ancora. –

0

Come abbiamo visto,

Non è possibile definire SET NULL nel record figlio quando le colonne bambino from e to non sono nulli.

Quindi se si tenta di creare le chiavi esterne con le seguenti 2 istruzioni, è necessario disporre delle chiavi esterne nella tabella 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) ; 

e

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

Speranza queste dichiarazioni aiutano.

Problemi correlati