Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Il vincolo di chiave esterna nella tabella figlio consente di inserire valori che non esistono nella tabella padre

Innanzitutto, abbiamo il pratico motivi. Le chiavi esterne vengono mantenute e controllate utilizzando gli indici. Affinché un indice sia utilizzabile, è necessario conoscere i valori (ricercati) di tutte le colonne all'interno dell'indice. Se abbiamo un index/pk su (a,b) e abbiamo un valore di chiave esterna di (NULL,1) , non possiamo cercare all'interno dell'indice per determinare se esiste una riga con un b valore di 1. Ciò renderebbe la chiave esterna "costosa" da mantenere.

Ma in secondo luogo, dobbiamo considerare la coerenza. Per il caso a colonna singola, è abbastanza incontrovertibile:se si dispone di un valore nella colonna FK, è necessario che ci sia un valore corrispondente nella colonna di riferimento. Altrimenti, se la colonna FK è NULL quindi il vincolo non viene verificato.

Ma come lo estendiamo a più colonne? Che cosa è la regola sopra? Non c'è un singolo interpretazione ovvia, ma invece multiple. La regola precedente è "se tutti le colonne non sono NULL, quindi il vincolo è selezionato" o "se qualsiasi le colonne non sono NULL, quindi il vincolo viene verificato"? Queste regole sono identiche quando viene presa in considerazione solo una singola colonna.

Ti aspettavi che la regola fosse la seconda, quando in realtà è la prima. Questo è esplicitamente documentato :