Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a: SQL Server 2016 (13.x) e versioni
successive database SQL di Azure
AzureSQL Managed Instance
SQL database in Microsoft Fabric
Le chiavi primarie e le chiavi esterne sono due tipi di vincoli che è possibile usare per applicare l'integrità dei dati nelle tabelle di SQL Server. Si tratta di importanti oggetti di database.
Vincoli della chiave primaria
Una tabella include in genere una colonna o una combinazione di colonne i cui valori identificano in modo univoco ogni riga della tabella. Questa colonna, o queste colonne, è detta chiave primaria (PK) della tabella e garantisce l'integrità dell'entità della tabella. Poiché i vincoli di chiave primaria garantiscono l'univocità dei dati, vengono spesso definiti su una colonna identity.
Quando si specifica un vincolo di chiave primaria per una tabella, il motore di database assicura l'univocità dei dati creando automaticamente un indice univoco per le colonne chiave primaria. Questo indice consente inoltre di accedere rapidamente ai dati quando si utilizza la chiave primaria nelle query. Se un vincolo di chiave primaria è definito su più di una colonna, i valori possono essere duplicati all'interno di una colonna, ma ciascuna combinazione di valori di tutte le colonne nella definizione del vincolo di chiave primaria deve essere univoca.
Le colonne ProductID e VendorID nella tabella Purchasing.ProductVendor costituiscono un vincolo di chiave primaria composto per la tabella, come illustrato nella figura seguente. Ciò assicura che ogni riga nella tabella ProductVendor contenga una combinazione univoca di ProductID e VendorID. e impedisce l'inserimento di righe duplicate.
- Una tabella può includere un solo vincolo di chiave primaria.
- Una chiave primaria non può superare 32 colonne e una lunghezza totale di 900 byte.
- Se l'indice viene generato da un vincolo di chiave primaria, nella tabella sarà possibile creare non più di 999 indici non cluster e di 1 indice cluster.
- Se per un vincolo di chiave primaria non viene specificato CLUSTERED o NONCLUSTERED, viene usato CLUSTERED se nella tabella non è presente alcun indice clustered.
- Tutte le colonne specificate in un vincolo di chiave primaria devono essere definite come NOT NULL. Se la nullabilità non è specificata, per tutte le colonne che partecipano a un vincolo di chiave primaria viene impostata l'opzione NOT NULL.
- Se si definisce una chiave primaria in una colonna di tipo CLR definito dall'utente, è necessario che l'implementazione del tipo supporti l'ordinamento binario.
Vincoli di chiave esterna
Per chiave esterna si intende una colonna o combinazione di colonne utilizzata per stabilire e applicare un collegamento tra i dati di due tabelle per controllare i dati che possono essere archiviati nella tabella della chiave esterna. In un riferimento a una chiave esterna viene creato un collegamento tra tabelle quando le colonne contenenti il valore della chiave primaria per una tabella vengono utilizzate come riferimento dalle colonne di un'altra tabella. Questa colonna diventa una chiave esterna nella seconda tabella.
Nella tabella Sales.SalesOrderHeader, ad esempio, è incluso un collegamento di chiave esterna alla tabella Sales.SalesPerson, in quanto esiste una relazione logica tra gli ordini di vendita e i venditori. La colonna SalesPersonID nella tabella SalesOrderHeader corrisponde alla colonna chiave primaria della tabella SalesPerson. La colonna SalesPersonID nella tabella SalesOrderHeader è la chiave esterna della tabella SalesPerson. Creando questa relazione di chiave esterna, non è possibile inserire un valore per SalesPersonID nella tabella SalesOrderHeader se non esiste già nella tabella SalesPerson.
Una tabella può fare riferimento a un massimo di 253 altre tabelle e colonne come chiavi esterne (riferimenti in uscita). In SQL Server 2016 (13.x) il limite per il numero di altre tabelle e colonne che possono fare riferimento alle colonne in una singola tabella (riferimenti in ingresso) è stato aumentato da 253 a 10.000. (richiede almeno il livello di compatibilità 130). All'incremento vengono applicate le seguenti restrizioni:
Più di 253 riferimenti a chiavi esterne sono supportati solo per le operazioni
DELETEDML. Le operazioniUPDATEeMERGEnon sono supportate.Una tabella con un riferimento di chiave esterna a se stessa è comunque limitata a 253 riferimenti di chiave esterna.
Più di 253 riferimenti a chiavi esterne non sono attualmente supportati per gli indici columnstore, le tabelle ottimizzate per la memoria, Stretch Database o le tabelle con chiavi esterne partizionate.
Important
Stretch Database è deprecato in SQL Server 2022 (16.x) e database SQL di Azure. Questa funzionalità verrà rimossa nelle versioni future del motore di database. Evitare di usare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.
Indici sui vincoli di chiave esterna
A differenza di quanto avviene per i vincoli di chiave primaria, la creazione di un vincolo di chiave esterna non determina automaticamente la creazione di un indice corrispondente. La creazione manuale di un indice in una chiave esterna, tuttavia, rappresenta spesso un'operazione utile per i motivi seguenti:
Le colonne chiave esterna vengono in genere utilizzate nei criteri di join quando i dati provenienti da tabelle correlate vengono riuniti in query confrontando le colonne nel vincolo di chiave esterna di una tabella con le colonne chiave primaria o univoca nell'altra tabella. Un indice consente al motore di database di trovare rapidamente i dati correlati nella tabella della chiave esterna. La creazione di questo indice, tuttavia, non è un requisito necessario. È possibile riunire i dati di due tabelle correlate anche se non è stato definito alcun vincolo di chiave primaria o di chiave esterna tra le tabelle, ma una relazione di chiave esterna tra due tabelle indica che le due tabelle sono state ottimizzate per essere riunite in una query che utilizza le chiavi come criteri.
Le modifiche apportate ai vincoli di chiave primaria vengono confrontate con i vincoli di chiave esterna nelle tabelle correlate.
Integrità referenziale
Benché lo scopo primario di un vincolo di chiave esterna consista nel controllare i dati che è possibile archiviare nella tabella della chiave esterna, tale vincolo controlla inoltre le modifiche apportate ai dati nella tabella della chiave primaria. Se, ad esempio, la riga relativa a un venditore viene eliminata dalla tabella Sales.SalesPerson e l'ID del venditore viene usato per gli ordini di vendita inclusi nella tabella Sales.SalesOrderHeader, viene interrotta l'integrità relazionale tra le due tabelle. Gli ordini di vendita del venditore eliminato risultano isolati (orfani) nella tabella SalesOrderHeader e privi di un collegamento ai dati inclusi nella tabella SalesPerson.
Un vincolo di chiave esterna impedisce questa situazione. Il vincolo garantisce l'integrità referenziale assicurando che non sia possibile apportare modifiche ai dati nella tabella della chiave primaria se tali modifiche invalidano il collegamento ai dati nella tabella con chiave esterna. Se si tenta di eliminare la riga in una tabella della chiave primaria oppure di modificare un valore della chiave primaria, l'azione ha esito negativo se il valore della chiave primaria eliminato o modificato corrisponde a un valore nel vincolo di chiave esterna di un'altra tabella. Per modificare o eliminare correttamente una riga in un vincolo di chiave esterna, è necessario innanzitutto modificare o eliminare i dati della chiave esterna nella tabella della chiave esterna e collegare quindi la chiave esterna ad altri dati della chiave primaria.
Integrità referenziale a catena
I vincoli di integrità referenziale di propagazione consentono di definire le operazioni eseguite dal motore di database quando un utente tenta di eliminare o aggiornare una chiave alla quale fa riferimento una chiave esterna. È possibile definire le azioni di propagazione seguenti.
NO ACTIONIl motore di database genera un errore e l'azione di eliminazione o aggiornamento della riga nella tabella padre viene annullata.
CASCADELe righe corrispondenti vengono aggiornate o eliminate nella tabella di riferimento quando la riga viene aggiornata o eliminata nella tabella padre. Non è possibile specificare la clausola
CASCADEse nella chiave esterna o nella chiave di riferimento è presente una colonna data e ora. Non è possibile specificareON DELETE CASCADEper una tabella con un triggerINSTEAD OF DELETE. Non è possibile specificareON UPDATE CASCADEper tabelle in cui sono presenti triggerINSTEAD OF UPDATE.SET NULLTutti i valori che costituiscono la chiave esterna vengono impostati su
NULLquando viene aggiornata o eliminata la riga corrispondente nella tabella padre. Affinché questo vincolo venga applicato, le colonne della chiave esterna devono poter contenere valori null. Non può essere specificato per le tabelle in cui sono presenti triggerINSTEAD OF UPDATE.SET DEFAULTTutti i valori che compongono la chiave esterna vengono impostati sui rispettivi valori predefiniti se viene eliminata o aggiornata la riga corrispondente nella tabella padre. Per l'esecuzione di questo vincolo, è necessario che per tutte le colonne chiave esterna siano definiti valori predefiniti. Se una colonna ammette i valori Null e non viene impostato un valore predefinito esplicito,
NULLdiventa il valore predefinito implicito della colonna. Non può essere specificato per le tabelle in cui sono presenti triggerINSTEAD OF UPDATE.
È possibile combinare le azioni CASCADE, SET NULL, SET DEFAULT e NO ACTION in tabelle con relazioni referenziali reciproche. Se il motore di database rileva l'azione NO ACTION, l'operazione viene arrestata e viene eseguito il rollback delle azioni CASCADE, SET NULL e SET DEFAULT correlate. Quando un'istruzione DELETE genera una combinazione di azioni CASCADE, SET NULL, SET DEFAULT o NO ACTION, tutte le azioni CASCADE, SET NULL e SET DEFAULT vengono applicate prima che il motore di database controlli la presenza di eventuali NO ACTION.
Trigger e azioni referenziali a catena
Le azioni referenziali a catena attivano i trigger AFTER UPDATE o AFTER DELETE come segue:
Vengono eseguite per prime tutte le operazioni referenziali di propagazione determinate direttamente dall'istruzione
DELETEoUPDATEoriginale.Se nelle tabelle interessate sono stati definiti trigger
AFTER, tali trigger vengono attivati dopo che sono state eseguite tutte le operazioni di propagazione. L'ordine di attivazione dei trigger è inverso rispetto all'ordine delle operazioni di propagazione. Se in una tabella sono presenti più trigger, tali trigger vengono attivati in ordine casuale a meno che per la tabella non sia stato specificato un primo o un ultimo trigger dedicato. L'ordine viene specificato usando sp_settriggerorder.Se dalla tabella che rappresenta la destinazione diretta di un'azione
UPDATEoDELETEvengono originate più catene di propagazione, l'ordine di attivazione dei rispettivi trigger non è specificato. Prima che una catena inizi ad attivare i propri trigger è tuttavia necessario che un'altra catena abbia completato l'attivazione di tutti i relativi trigger.Un trigger
AFTERpresente nella tabella di destinazione diretta di un'azioneUPDATEoDELETEviene attivato indipendentemente dal fatto che influisca o meno su qualsiasi riga. In questo caso, la propagazione non avrà effetti su nessun'altra tabella.Se uno dei trigger precedenti esegue operazioni
UPDATEoDELETEsu altre tabelle, tali operazioni possono avviare catene di propagazione secondarie Queste catene secondarie vengono elaborate una alla volta per ogni operazioneUPDATEoDELETE, dopo l'attivazione di tutti i trigger in tutte le catene primarie. È possibile ripetere il processo in modo ricorsivo per le operazioniUPDATEoDELETEsuccessive.L'esecuzione di
CREATE,ALTER,DELETEo di altre istruzioni del linguaggio di definizione dei dati (DDL) all'interno dei trigger può causare l'attivazione dei trigger DDL. Ciò potrebbe successivamente eseguire operazioni DELETE o UPDATE che avviano ulteriori catene ed eventi attivatori a cascata.Se viene generato un errore all'interno di una specifica catena di azioni referenziali a catena, viene segnalato un errore, in tale catena non viene attivato alcun trigger
AFTERe viene eseguito il rollback dell'operazione DELETE o UPDATE che ha creato la catena.Una tabella in cui è presente un trigger
INSTEAD OFnon può inoltre includere un clausolaREFERENCESche specifica un'operazione di propagazione. Un triggerAFTERin una tabella di destinazione di un'operazione di propagazione può tuttavia eseguire un'istruzioneINSERT,UPDATEoDELETEsu un'altra tabella o vista che attiva un triggerINSTEAD OFdefinito nell'oggetto specifico.
Contenuti correlati
- Creare chiavi primarie
- Eliminare chiavi primarie
- Modificare chiavi primarie
- Creare relazioni di chiave esterna
- Modificare relazioni di chiave esterna
- Eliminazione delle relazioni con chiave esterna
- Visualizzare proprietà di chiave esterna
- Disabilitare i vincoli di chiave esterna per la replica
- Disabilitare i vincoli di chiave esterna con le istruzioni INSERT e UPDATE