2011-12-17 15 views
5

Sto provando a creare una relazione uno a molti usando una tabella. È possibile?Uno a molti con un tavolo

create table user(id int primary key auto_increment not null,                              
created_by int default null                                       
)ENGINE=INNODB;                                          

alter table user add foreign key (created_by) references user(id) ON DELETE SET NULL ON UPDATE CASCADE;                    

insert into user (id) VALUES(1);                                     
insert into user (id, created_by) VALUES (2,1); 

Ora quando elimino utente con id = 1 il valore di created_by automaticamente passare a NULL come mi aspettavo.

Ma quando cambio id dell'utente con id = 1 ottengo questo errore

mysql> update user set id=2 where id=1; 
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`jrt`.`user`, CONSTRAINT `user_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE) 

Come posso risolvere questo problema? Affter questo aggiornamento Voglio che la colonna created_by sia modificata in cascata.

+0

Dove hai bisogno di un tale concetto? - solo curioso. – Lion

+0

Non ne ho affatto bisogno. Sono solo curioso. – mecio

+0

Tim Gee collega un thread del forum con la risposta esatta (è un meccanismo semplice per prevenire loop infiniti), assicurati di leggere [il followup] (http://forums.mysql.com/read.php?136,391782,398085 # msg-398.085). –

risposta

2

Le chiavi non sono destinate a essere modificate, sono pensate per essere "identificative". Quindi l'utente con id 2 è logicamente un utente diverso con l'utente con id 1. Nel momento in cui crei un utente unico, la sua chiave primaria dovrebbe essere la stessa per tutta la vita di quell'utente.

Quindi questo è davvero un problema di progettazione. Devi chiedere perché vuoi cambiare l'ID per un particolare utente. Potrebbe essere che ciò che si desidera sia una chiave di identificazione fissa E un altro identificatore (che non è la chiave ed esiste solo sulla tabella utente) che è possibile modificare.

[Aggiornato con ulteriori informazioni] Ecco una risorsa (ce ne sono molti disponibili online) sui fondamenti della progettazione di database relazionali. http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

La sezione pertinente è "Tabelle, univocità e chiavi".

Fabian Pascal, nel suo libro SQL e nozioni di base relazionali, rileva che la decisione dovrebbe essere basata sui principi di minimalità (scegliere le colonne minor numero necessario), stabilità (scegliere una chiave che raramente modifiche), e semplicità/familiarità (scegli una chiave semplice sia che familiare agli utenti).

Personalmente, andrei oltre la stabilità; prova a scegliere una chiave che non cambi mai. Ad esempio, "email" sarebbe una cattiva scelta della chiave per un utente in quanto gli utenti possono cambiare la propria email. Se si sceglie una chiave, come un numero generato internamente o forse un identificatore univoco dal sistema del personale, non si deve mai preoccuparsi di cambiare e migrare questa modifica ad altre tabelle.

Nota: ci possono essere casi in cui come "una tantum" è necessario modificare una chiave primaria. Ciò è meglio fare con alcune istruzioni SQL manuali (eliminare il primo utente e creare un secondo utente identico con una chiave diversa). Tuttavia, non dovrebbe far parte del design del database, il che implica la natura automatizzata di un aggiornamento in cascata.

Vedi anche:When to use "ON UPDATE CASCADE"

ANCHE NOTA:http://forums.mysql.com/read.php?136,391782,391782

+0

Stavo pensando a 'update user set id = 5 dove id = 1; ' – mecio

+0

Diciamo che abbiamo un indirizzo email invece di id. L'utente vuole appendere la sua email ed è anche la chiave primaria della tabella come nell'esempio sopra. – mecio

+0

Sì, si tratta di una cattiva progettazione del database e quindi non esiste un modo automatico per applicare un tale cambiamento a cascata perché non dovresti farlo. Aggiornerò la mia risposta per fornire una risorsa esterna con chiarimenti. –

Problemi correlati