La relazione uno a uno è normalizzata?


12

Considera che abbiamo un ampio set di dati statistici per un record; ad es. 20-30 INTcolonne. È meglio mantenere l'intero set in una tabella poiché appartengono tutti a un record O creare un'altra tabella connessa con una relazione uno a uno.

Il vantaggio del primo è quello di evitare JOINe avere un rapido accesso a tutti i dati statistici per il record corrispondente.

Il vantaggio di quest'ultimo è di mantenere in ordine la colonna. La prima colonna è ad alta intensità di lettura e la seconda ad alta intensità di scrittura. Naturalmente, penso che non abbia alcun effetto significativo sulle prestazioni, poiché utilizzo InnoDB con il blocco a livello di riga.

In generale, voglio sapere se è pratico separare diversi set di dati per un singolo record?


2
'Normalizzato' significa prima forma normale (1NF) ed è un requisito fondamentale del modello relazionale. "Completamente normalizzato" significa 5 NF o superiore. La tabella "relazione uno a uno" proposta ha maggiori possibilità di trovarsi in una forma normale più alta (possibilmente anche in 6NF) rispetto a quella attuale perché è decomposta! Quali forme normali soddisfa la tua tabella esistente?
onedayquando il

@onedaywhen Come molti altri non seguo la normalizzazione passo dopo passo, poiché a volte è utile anche la de-normalizzazione. In generale, l'intero database dovrebbe avere un livello di normalizzazione tra 3NF - 5NF (ho sempre problemi con 4NF!)
Googlebot

Risposte:


19

Se rientra nelle regole della normalizzazione, allora le relazioni 1: 1 possono essere normalizzate (per definizione!) - In altre parole, non c'è nulla sulle relazioni 1: 1 che rendono impossibile per loro obbedire alle forme normali.

Per rispondere alla tua domanda sulla praticità delle relazioni 1: 1, ci sono momenti in cui questo è un costrutto perfettamente utile, come quando hai sottotipi con predicati distinti (colonne).

Le ragioni per cui dovresti usare le relazioni 1: 1 dipendono dal tuo punto di vista. I DBA tendono a pensare a tutto come a una decisione sulle prestazioni. Modellatori di dati e programmatori tendono a pensare a queste decisioni come progettate o orientate al modello. In effetti, vi è molta sovrapposizione tra questi punti di vista. Dipende da quali sono le tue prospettive e priorità. Ecco alcuni esempi di motivazioni per le relazioni 1: 1:

  • Hai un sottoinsieme di colonne molto larghe e vuoi separarle fisicamente nella memoria per motivi di prestazioni.

  • Esistono alcuni sottogruppi di colonne che non vengono letti o aggiornati frequentemente e si desidera tenerli separati dalle colonne utilizzate di frequente per motivi di prestazioni.

  • Hai alcune colonne che sono opzionali in generale ma sono obbligatorie quando sai che il record è di un certo tipo.

  • Hai alcune colonne che logicamente si uniscono per un sottotipo e vuoi modellarle per adattarle bene al modello a oggetti del tuo codice.

  • Hai alcune colonne che possono essere applicate solo ad alcuni sottotipi di un super-tipo di entità e desideri che il tuo schema imponga l'assenza di questi dati per altri sottotipi.

  • Hai alcune colonne che appartengono a un'entità ma devi proteggere queste colonne particolari usando regole di accesso più restrittive (ad es. Stipendio su una tabella dei dipendenti).

Quindi puoi vedere, a volte il driver è prestazioni, a volte è purezza del modello o solo il desiderio di sfruttare appieno le regole dello schema dichiarativo.


You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.In che modo la loro separazione migliora le prestazioni (supponendo che le colonne siano sempre accessibili ogni volta che la tabella principale è)?
Gili,

@Gili - Se la tua ipotesi fosse vera, questo caso non si applicherebbe. La separazione di colonne di grandi dimensioni e raramente necessarie consente a più righe di adattarsi a una pagina, consentendo in tal modo un recupero più rapido delle colonne di uso comune. Ovviamente la lettura delle colonne segregate insieme alle colonne comunemente utilizzate sarebbe più lenta poiché è necessario un join.
Joel Brown,

Voglio segregare lungo le colonne comunemente utilizzate per motivi di progettazione (separazione delle preoccupazioni, maggiore riutilizzo del codice). Qualcuno ha pubblicato una stima del costo di tali join? Sono trascurabili o qualcosa di cui dovrei preoccuparmi a lungo termine?
Gili,

@Gili - re: il costo dei join: non esiste una risposta corretta a questa domanda oltre a "dipende". Il costo di partecipazione è influenzato da molti fattori. Se siano trascurabili è ancora più difficile rispondere, perché alla fine è soggettivo. Il modo migliore per rispondere alla tua domanda è prendere in giro alcuni dati di test ed eseguire test di volume. Provalo in entrambi i modi e vedi se riesci a distinguere usando i volumi di dati del mondo reale (qualunque cosa ciò implichi per la tua applicazione).
Joel Brown,

L'ho fatto e ho ottenuto risultati sorprendenti: dba.stackexchange.com/q/74693/4719 Ammetto che questo non è un tipico esempio di normalizzazione, ma non evidenzia che i JOIN sono (ancora) molto costosi.
Gili,

4

I motivi principali per cui utilizzare una mappatura uno a uno per suddividere una tabella di grandi dimensioni in due sono ad esempio per motivi di prestazioni:

a) La tabella contiene dati binari / clob / blob in una tabella a cui si accede frequentemente rallentando le prestazioni poiché le colonne di grandi dimensioni vengono gestite in modo diverso.

b) La tabella ha molte colonne alle quali si accede da query diverse, quindi le prestazioni sono ridotte, pertanto è necessario spostare le colonne correlate in una tabella separata per migliorare le prestazioni di accesso

Tuttavia, avere molte colonne intere non giustifica lo sforzo aggiuntivo di suddividere la tabella in tabelle separate e di doverle interrogare.


ottimo punto per chiarire il problema!
Googlebot,
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.