PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Cosa fare con i valori null durante la modellazione e la normalizzazione?

SQL tratta NULL specialmente per la sua versione di 3VL (logica a 3 valori). La normalizzazione e altre teorie relazionali no. Tuttavia, possiamo tradurre i progetti SQL in progetti relazionali e viceversa. (Presumi che non ci siano righe duplicate qui.)

La normalizzazione avviene per le relazioni ed è definito in termini di operatori che non trattano NULL in modo speciale. Il termine "normalizzazione" ha due significati distinti più comuni:mettere una tabella in "1NF" e in "NF superiori (forme normali)". NULL non influisce sulla "normalizzazione a 1NF". "Normalizzazione a NF superiori" sostituisce una tabella con tabelle più piccole che si uniscono naturalmente ad essa. Ai fini della normalizzazione è possibile trattare NULL come un valore consentito nel dominio di una colonna nullable oltre ai valori del suo tipo SQL. Se le nostre tabelle SQL non hanno NULL, possiamo interpretarle come relazioni e join SQL ecc. Come join, ecc. Ma se scomponi dove una colonna nullable è stata condivisa tra i componenti, renditi conto che per ricostruire l'originale in SQL devi unire SQL su colonne con lo stesso nome sono uguali o entrambe NULL . E non vorrai tali CK (chiavi candidati) in un database SQL. Ad esempio, non puoi dichiararlo come SQL PK (chiave primaria) perché ciò significa UNIQUE NOT NULL. Ad esempio, un vincolo UNIQUE che coinvolge una colonna nullable consente più righe che hanno un NULL in quella colonna, anche se le righe hanno gli stessi valori in ogni colonna. Ad esempio, i NULL negli FK SQL li soddisfano (in vari modi per modalità MATCH), in modo che non vengano visualizzati nella tabella di riferimento. (Ma i DBMS differiscono in modo idiosincratico dall'SQL standard.)

Sfortunatamente la scomposizione potrebbe portare a una tabella con tutti CK contenenti NULL, quindi non abbiamo nulla da dichiarare come SQL PK o UNIQUE NOT NULL. L'unica soluzione sicura è convertire in un design privo di NULL. Dopo la normalizzazione, potremmo voler reintrodurre un po' di nullability nei componenti.

In pratica riusciamo a progettare le tabelle in modo che ci sia sempre un insieme di colonne prive di NULL che possiamo dichiarare come CK, tramite SQL PK o UNIQUE NOT NULL. Quindi possiamo eliminare una colonna nullable eliminandola dalla tabella e aggiungendo una tabella con quella colonna e le colonne di alcuni CK privi di NULL:se la colonna non è NULL per una riga nel vecchio design, allora una riga con il valore del sopracciglio CK e della colonna va nella tabella aggiunta; altrimenti è NULL nel vecchio design e nessuna riga corrispondente è nella tabella aggiunta. (La tabella originale è una naturale unione a sinistra di quelle nuove.) Ovviamente, dobbiamo anche modificare le query dal vecchio design al nuovo design.

Possiamo sempre evitare NULL tramite un design che aggiunge una colonna booleana per ogni vecchia colonna nullable e ha la vecchia colonna NOT NULL. La nuova colonna dice per una riga se la vecchia colonna era NULL nel vecchio design e quando true ha la vecchia colonna essere un valore che selezioniamo a tale scopo per quel tipo in tutto il database. Ovviamente, dobbiamo anche modificare le query dal vecchio design al nuovo design.

Se vuoi evitare NULL è una domanda separata. Il tuo database potrebbe in qualche modo essere "migliore" o "peggiore" per la tua applicazione con entrambi i design. L'idea alla base dell'evitare NULL è che complica i significati delle query, quindi complica le query, in modo perverso, rispetto alla complicazione di più join da più tabelle prive di NULL. (Quella perversità viene in genere gestita rimuovendo i NULL nelle espressioni di query il più vicino possibile a dove appaiono.)

PS Molti termini SQL, inclusi PK e FK, differiscono dai termini relazionali. SQL PK significa qualcosa di più simile a superkey; SQL FK significa qualcosa di più simile a una superchiave esterna; ma non ha nemmeno senso parlare di una "superchiave" in SQL:

A causa della somiglianza delle tabelle SQL con le relazioni, i termini che coinvolgono le relazioni vengono applicati in modo sciatto alle tabelle. Ma anche se puoi prendere in prestito termini e dare loro significati SQL:valore, tabella, FD (dipendenza funzionale), superkey, CK (chiave candidata), PK (chiave primaria), FK (chiave esterna), join e, predicato, NF (forma normale), normalizzare, 1NF, ecc. Non puoi semplicemente sostituire quei significati SQL con quelle parole nelle definizioni RM, teoremi o algoritmi e ottenere qualcosa di sensato o vero. Inoltre presentazioni SQL delle nozioni di RM quasi mai in realtà ti dirà come applicare correttamente le nozioni di RM a un database SQL . Si limitano a ripetere a pappagallo le presentazioni RM, ignari del fatto che il loro uso dei significati SQL per i termini renda le cose prive di senso o non valide.