2013-09-08 21 views
30

Penso solo che la risposta sia falsa perché la chiave esterna non ha la proprietà uniqueness.la chiave esterna può fare riferimento alla chiave primaria nella stessa tabella?

Ma alcune persone hanno detto che può essere in caso di auto che si unisce al tavolo. Sono nuovo a SQL. Se è vero per favore spiega come e perché?

Employee table 
| e_id | e_name | e_sala | d_id | 
|---- |------- |----- |--------| 
| 1 | Tom | 50K | A | 
| 2 | Billy | 15K | A | 
| 3 | Bucky | 15K | B | 


department table 
| d_id | d_name | 
|---- |------- | 
| A | XXX | 
| B | YYY | 

Ora d_id è una chiave esterna, quindi come può essere la chiave primaria. E spiega qualcosa su join. Qual è il suo uso?

+0

@ sarwar026, la domanda non è esattamente ciò che l'OP chiedeva qui ... – ryvantage

+0

È possibile aggiungere quale DBMS si sta utilizzando in modo da ottenere esempi che funzionino per il DBMS. –

+0

sto usando ORACLE 9.0 – AmanS

risposta

38

Penso che la domanda sia un po 'confusa.

Se si intende "la chiave esterna può 'fare riferimento' a una chiave primaria nella stessa tabella?", La risposta è ferma come alcuni hanno risposto. Ad esempio, in una tabella dei dipendenti, una riga per un dipendente può avere una colonna per la memorizzazione del numero di dipendenti del manager in cui il manager è anche un dipendente e quindi avrà una riga nella tabella come una riga di qualsiasi altro dipendente.

Se si intende "colonna (o insieme di colonne) può essere una chiave primaria e una chiave esterna nella stessa tabella?", La risposta, a mio avviso, è un no; sembra senza significato. Tuttavia, la seguente definizione ha esito positivo in SQL Server!

Ma penso che non abbia senso avere un tale limite a meno che qualcuno non fornisca un esempio pratico.

AmanS, nel proprio esempio d_id in nessuna circostanza può essere una chiave primaria nella tabella Employee. Una tabella può avere solo una chiave primaria. Spero che questo chiarisca il tuo dubbio. d_id è/può essere una chiave primaria solo nella tabella di dipartimento.

+0

mi è chiaro che d_id è la chiave primaria della tabella di dipartimento. anche d_id nella tabella dei dipendenti è una chiave esterna. e inoltre dici che d_id può essere la chiave primaria nella stessa tabella (dipendente). la mia insegnante mi ha detto che in caso di auto-adesione al tavolo dei dipendenti può essere possibile. questo punto non mi è chiaro come? – AmanS

+1

@AmanS, hai detto "dici che d_id può essere la chiave primaria nella stessa tabella (impiegato)". Ma non l'ho fatto; ecco la mia affermazione "AmanS, nel tuo esempio d_id in nessun caso può essere una chiave primaria nella tabella Employee". Spero che tu capisca Non è possibile nemmeno in caso di auto join. Un'altra colonna in una tabella può fare riferimento alla chiave primaria della stessa tabella. Per esempio. Crea dipendente tabella (chiave primaria e_id int, e_name varchar (30), e_mgr int, chiave esterna (e_mgr) referente dipendente (e_id)). Questo è un caso di auto join e e_mgr è una chiave esterna che fa riferimento alla chiave primaria e_id. – mvsagar

+0

puoi dirmi qualche esempio pratico con query in cui foreign può riferirsi alla chiave primaria? ma qui anche la persona sotto (ryvantage) ha detto che può .... io sono confuso per favore aiuto – AmanS

15

Certo, perché no? Diciamo che avere una tabella Person, con id, name, age, e parent_id, dove parent_id è una chiave esterna alla stessa tabella. Non è necessario normalizzare la tabella Person alle tabelle Parent e Child, che sarebbe eccessivo.

Person 
| id | name | age | parent_id | 
|----|-------|-----|-----------| 
| 1 | Tom | 50 |  null | 
| 2 | Billy | 15 |   1 | 

Qualcosa di simile.

Suppongo che per mantenere la coerenza, ci dovrebbe essere almeno 1 valore null per parent_id, però. La riga "alfa maschile".

MODIFICA: come mostrano i commenti, Sam ha trovato una buona ragione per non farlo. Sembra che in MySQL quando si tenta di apportare modifiche alla chiave primaria, anche se si specifica CASCADE ON UPDATE non propagherà correttamente la modifica. Sebbene le chiavi primarie siano (di solito) off-limits per l'editing in produzione, è comunque una limitazione da non ignorare. Così posso cambiare la mia risposta: si dovrebbe probabilmente evitare questa pratica a meno che non si ha il controllo abbastanza stretto sopra il sistema di produzione (e può garantire nessuno potrà implementare un controllo che modifica il PK). Non l'ho testato al di fuori di MySQL.

+0

basta vedere la mia domanda modificata con l'esempio. la tua risposta è ancora si? – AmanS

+0

Non funziona per 'update'. controlla http://sqlfiddle.com/#!9/445052/1/0 e prova ad aggiungere "Aggiorna menu set id = 6 WHERE id = 1;" otterrai '# 1451 - Impossibile eliminare o aggiornare una riga genitore ' – Sam

+0

@Sam due cose: 1) Vedo che non funziona, ma non sono d'accordo sul fatto che dovrebbe fallire. Con un aggiornamento a cascata, non sembra esserci alcuna ragione logica per cui l'aggiornamento dovrebbe fallire. 2) Chi cambia i PK in situazioni pratiche? Le persone che stanno cercando problemi lol – ryvantage

3

Ad esempio: n livello di sottocategoria per le categorie.Tabella sotto chiave primaria id viene definito da chiave esterna sub_category_id

enter image description here

0

Un buon esempio di utilizzo ids di altre righe della stessa tabella chiavi esterne vengono nidificati liste. L'eliminazione di una riga che ha figli (cioè, righe, chich si riferiscono all'ID del genitore), che ha anche un childred (cioè ID di riferimento dei bambini) ... cancellerà una cascata di righe. Sollevato un sacco di dolore (e un sacco di codice su cosa fare con gli orfani - cioè, le righe, che si riferiscono a ID non esistenti).

Problemi correlati