Qualche tempo fa, ho letto il libro SQL and Relational Theory by C. J. Date. L'autore è noto per aver criticato la logica a tre valori di SQL (3VL). 1)Opzioni per eliminare colonne NULLable da un modello DB (per evitare la logica a tre valori di SQL)?
l'autore fa alcuni punti di forza sul perché 3VL deve essere evitato in SQL, tuttavia egli non descrive come un modello di database potrebbe apparire come se le colonne nullable non era permesso. Ci ho pensato un po 'e ho trovato le seguenti soluzioni. Se mi mancassero altre opzioni di design, mi piacerebbe sentir parlare di loro!
1) critica di Data di 3VL di SQL è a sua volta stato criticato troppo: vedi this paper by Claude Rubinson (include la critica originale di C. J. Data).
tabella Esempio:
Come esempio, assumere la seguente tabella dove abbiamo una colonna Null (DateOfBirth
):
# +-------------------------------------------+
# | People |
# +------------+--------------+---------------+
# | PersonID | Name | DateOfBirth |
# +============+--------------+---------------+
# | 1 | Banana Man | NULL |
# +------------+--------------+---------------+
Opzione 1: Emulazione di NULL
tramite un flag e un valore predefinito:
Invece di rendere nullable la colonna, viene specificato qualsiasi valore predefinito (ad es. 1900-01-01
). Una colonna aggiuntiva BOOLEAN
specificherà se il valore in DateOfBirth
deve semplicemente essere ignorato o se contiene effettivamente dati.
# +------------------------------------------------------------------+
# | People' |
# +------------+--------------+----------------------+---------------+
# | PersonID | Name | IsDateOfBirthKnown | DateOfBirth |
# +============+--------------+----------------------+---------------+
# | 1 | Banana Man | FALSE | 1900-01-01 |
# +------------+--------------+----------------------+---------------+
Opzione 2: attivare una colonna Null in una tabella separata:
La colonna Null è sostituita da una nuova tabella (DatesOfBirth
). Se un record non dispone di dati per quella colonna, non ci sarà un record nella nuova tabella:
# +---------------------------+ 1 0..1 +----------------------------+
# | People' | <-------> | DatesOfBirth |
# +------------+--------------+ +------------+---------------+
# | PersonID | Name | | PersonID | DateOfBirth |
# +============+--------------+ +============+---------------+
# | 1 | Banana Man |
# +------------+--------------+
Anche se questo sembra la soluzione migliore, questo sarebbe forse tradursi in molte tabelle che devono essere uniti per una singola query. Dal momento che OUTER JOIN
s non sarà consentito (perché introdurrebbe NULL
nel set di risultati), tutti i dati necessari potrebbero non essere più recuperati con una singola query come prima.
Domanda: ci sono altre opzioni per eliminare NULL
(e in caso affermativo, che cosa sono)?
potresti spiegare brevemente perché la logica dei tre valori dovrebbe essere evitata. La ragione per cui sono consapevole è che devi conservare almeno un altro po '. Ma se si aggiunge un'altra colonna, non ha senso.Anche un'altra tabella porta al sovraccarico della query. Un'altra ragione per cui posso pensare è che devi gestire il valore NULL, ma lo hai anche con le tue soluzioni. – TooAngel
@TooAngel: Non si tratta solo di dover archiviare un altro bit. Si tratta di ottenere risultati di query che non sembrano avere senso (comune), ad es. 'COUNT (*)' non conterà 'NULL', o che' NULL' non equivale mai 'NULL' (perché in pratica,' NULL' ha il significato di "sconosciuto"). - Ti suggerisco di leggere il documento di 5 pagine a cui mi sono collegato nella nota a piè di pagina. Contiene la critica di Date (apparentemente imperfetta, ma comunque molto perspicace) di 3VL. Inoltre, potresti voler controllare l'articolo di Wikipedia sulla logica ternaria: http://en.wikipedia.org/wiki/Ternary_logic – stakx
Per quanto sopra, dovrei aggiungere il punto principale, che è quello dovuto a volte "non intuitivo" risultati che puoi ottenere grazie a 3VL, i risultati sono facilmente interpretati male. O ancora peggio, una query non è ciò che si pensa sia, e si otterranno risultati (corretti) che non sembreranno giusti. Un ultimo punto è che 'NULL' è spesso usato per indicare cose diverse, ad es. "sconosciuto", "mancante", "non applicabile", ecc., che rende ancora più difficile formulare query corrette e interpretare correttamente il risultato ottenuto dal DB. – stakx