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

Progettazione di relazioni 1:1 e 1:m in SQL Server

Qualsiasi relazione richiede che la tabella "genitore" (da un lato) abbia una chiave primaria (o univoca) (PK), che identifichi in modo univoco ogni riga, e che la tabella "figlio" (l'altro lato) abbia una o più colonne di chiave esterna , che deve essere popolato con valori uguali ad alcuni valori esistenti della chiave primaria nella tabella padre. Se desideri una relazione uno a molti (1-M), la chiave esterna dovrebbe essere un attributo ordinario (colonna o colonne) nella tabella figlio che può essere ripetuto (possono esserci molte righe con lo stesso valore)

Se desideri una relazione uno a uno (1-1), la chiave esterna dovrebbe essere essa stessa una chiave primaria o un indice univoco nella tabella figlio che garantisce che potrebbe esserci al massimo una riga nella tabella figlio con quel valore.

Una relazione 1-1 partiziona efficacemente gli attributi (colonne) in una tabella in due tabelle. Questa è chiamata segmentazione verticale. Questo è spesso fatto per sottoclassi le entità della tabella o, per un altro motivo, se i modelli di utilizzo nelle colonne della tabella indicano che è necessario accedere ad alcune colonne con una frequenza significativamente maggiore rispetto al resto delle colonne. (Supponiamo che si accederà a una o due colonne migliaia di volte al secondo e alle altre 40 colonne solo una volta al mese). Il partizionamento della tabella in questo modo ottimizzerà effettivamente il modello di archiviazione per queste due diverse query.

Sottoclassi . Quanto sopra crea effettivamente una relazione da 1 a zero o uno, che viene utilizzata per quella che viene chiamata una relazione di sottoclasse o sottotipo. Ciò si verifica quando si hanno due entità diverse che condividono un gran numero di attributi, ma una delle entità ha attributi aggiuntivi di cui l'altra non ha bisogno. Un buon esempio potrebbe essere Dipendenti e Dipendenti stipendiati . Il Dipendente la tabella avrebbe tutti gli attributi condivisi da tutti i dipendenti e SalariedEmployee la tabella esisterebbe in una relazione (1-0/1) con Dipendenti, con gli attributi aggiuntivi (Stipendio , Vacanze annuali , ecc.) di cui hanno bisogno solo i dipendenti stipendiati.

Se vuoi davvero una relazione 1-1, devi aggiungere un altro meccanismo per garantire che la tabella figlio abbia sempre un record per ogni record/riga nella tabella padre. In genere l'unico modo per farlo è applicarlo nel codice utilizzato per inserire i dati (in un trigger, in una procedura memorizzata o in un codice esterno al database). Questo perché se hai aggiunto vincoli di integrità referenziale su due tabelle che richiedono che le righe siano sempre in entrambe, non sarebbe possibile aggiungere una riga a nessuna delle due senza violare uno dei vincoli e non puoi aggiungere una riga a entrambe tavoli contemporaneamente.