Perché una tabella dovrebbe usare la sua chiave primaria come chiave esterna per se stessa


21

Guardando attraverso un database, mi sono imbattuto in una tabella che utilizzava la sua chiave primaria come chiave esterna a se stessa.

Ho visto che una tabella può avere una chiave esterna su se stessa per costruire una struttura gerarchica, ma userebbe un'altra colonna per fare riferimento alla chiave primaria.

Dal momento che la chiave primaria è unica, in questa situazione la riga non potrebbe solo tornare a se stessa? Questo sembra essere un collegamento tautologico, poiché se ho già la fila, allora ho già la fila.

C'è qualche motivo per farlo?

Tavolo unito a se stesso

Sono certo che il vincolo sia scritto in quel modo (non solo guardando il diagramma) perché la stessa tabella e colonna sono usate per entrambe le metà della definizione.


6
Probabilmente la mia teoria è quella
Martin Smith,

Risposte:


28

Come hai detto. Un FOREIGN KEYvincolo che fa riferimento alla stessa tabella è in genere per una struttura gerarchica e utilizza un'altra colonna per fare riferimento alla chiave primaria. Un buon esempio è una tabella di dipendenti:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Quindi in questo caso esiste una chiave esterna dalla tabella a se stessa. Tutti i manager sono anche dipendenti, quindi in ManagerIdrealtà è EmployeeIdil manager.

D'altra parte, se vuoi dire che qualcuno ha usato la EmployeeIdchiave esterna per tornare alla tabella Employee , probabilmente è stato un errore . Ho fatto un test ed è possibile ma non avrebbe avuto alcun uso reale.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);

1
Porre un vincolo su ManagerId relativo a EmployeeId in questo caso potrebbe essere utile se il Manger dovesse essere "separato". Non consentirebbe l'eliminazione della riga se impostata in questo modo. Non dire che lo farei in questo modo, ma potrebbe avere qualche vantaggio se la tua domanda si basasse su dipendenti con manager.
zgr024,

6

Ho appena trovato una chiave esterna simile nel mio db e deve essere stata io stessa a crearla. Penso che sia successo per caso. Se faccio clic su "Nuova chiave esterna" nel menu di scelta rapida di una tabella con chiave primaria (in Management Studio, SQL 2014 Express), questa crea già automaticamente una chiave esterna di questo tipo che fa riferimento a se stessa. Vedi sotto:

inserisci qui la descrizione dell'immagine

Se poi non mi rendo conto che dovrei modificarlo invece di aggiungerne uno nuovo, rimarrà lì. Oppure, se faccio semplicemente clic sul pulsante [Chiudi] significa che sarebbe come un [Annulla], la chiave esterna verrà comunque creata dopo aver salvato la definizione della tabella.

Quindi, per me una tale chiave esterna non ha senso e può essere rimossa.


È possibile che tu volessi creare un FK e nel processo ti rendi conto che l'altra tabella non ha ancora impostato il suo PK, quindi annulli, vai all'altra tabella e poi per qualche motivo dimentichi di continuare con il processo FK. Ecco il tuo FK ricorsivo.
Andrew,

4

Forse il designer ha voluto disabilitare l'uso di TRUNCATE TABLE?

TRUNCATE TABLEnon può essere utilizzato su una tabella con un vincolo di chiave esterna rispetto a un'altra tabella, sebbene possa essere utilizzato in presenza di chiavi esterne autoreferenziali . Dalla documentazione per TRUNCATE TABLE (Transact-SQL) :

Estratto di BOL

Una DELETEdichiarazione senza una WHEREclausola di ha un effetto simile a un TRUNCATE TABLE(rimuovere tutte le righe della tabella), ma la DELETEdichiarazione spara trigger di eliminazione, che potrebbe essere un motivo per permettere DELETE, ma non TRUNCATE TABLE.

Lo farei usando le autorizzazioni ( DELETErichiede l'autorizzazione per l'eliminazione, TRUNCATE TABLErichiede l' autorizzazione per alterare la tabella), ma forse c'è qualche ragione per cui il designer non è stato in grado di farlo?

Nota: anche se ciò che il designer ha fatto in realtà non disabilita l'uso di TRUNCATE TABLE, sto ancora ipotizzando che questo fosse il loro intento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.