Spero di chiarire qui la mia posizione.
Quello NULL = NULL
valutare FALSE
è sbagliato. Hacker e Mister hanno risposto correttamente NULL
. Ecco perché. Dewayne Christensen mi ha scritto, in un commento a Scott Ivey :
Dato che è dicembre, usiamo un esempio stagionale. Ho due regali sotto l'albero. Ora, dimmi se ne ho due o meno della stessa cosa.
Possono essere diversi o possono essere uguali, non si sa fino a quando non si aprono entrambi i regali. Chissà? Hai invitato due persone che non si conoscono ed entrambe ti hanno fatto lo stesso dono - raro, ma non impossibile § .
Quindi la domanda: questi due UNKNOWN presentano gli stessi (uguale, =)? La risposta corretta è: SCONOSCIUTO (cioè NULL
).
Questo esempio aveva lo scopo di dimostrare che ".. ( false
o null
, a seconda del sistema) .." è una risposta corretta - non lo è, è corretto solo NULL
in 3VL (o è accettabile accettare un sistema che fornisce risposte sbagliate? )
Una risposta corretta a questa domanda deve sottolineare questi due punti:
- la logica a tre valori (3VL) è controintuitiva (vedere innumerevoli altre domande su questo argomento su Stackoverflow e in altri forum per essere sicuri);
- I DBMS basati su SQL spesso non rispettano nemmeno i 3VL, a volte danno risposte errate (come afferma il poster originale, in questo caso SQL Server fa).
Quindi ribadisco: SQL non serve a nulla forzare l'interpretazione della proprietà riflessiva dell'uguaglianza, che afferma che:
for any x, x = x
§§ (in parole povere : qualunque sia l'universo del discorso, una "cosa" è sempre uguale a se stessa ).
.. in un 3VL ( TRUE
, FALSE
, NULL
). L'aspettativa delle persone sarebbe conforme a 2VL ( TRUE
, FALSE
che anche in SQL è valido per tutti gli altri valori), vale a dire x = x
sempre valutare TRUE
, per ogni possibile valore di x - nessuna eccezione.
Si noti inoltre che i NULL sono " non valori " validi (come i loro apologeti fingono di essere) che si possono assegnare come valori di attributo (??) come parte delle variabili di relazione. Quindi sono valori accettabili di ogni tipo (dominio), non solo del tipo di espressioni logiche.
E questo era il mio punto :, NULL
come valore, è una "strana bestia". Senza eufemismo, preferisco dire: sciocchezze .
Penso che questa formulazione sia molto più chiara e meno discutibile - mi dispiace per la mia scarsa conoscenza della lingua inglese.
Questo è solo uno dei problemi dei NULL. Meglio evitarli del tutto, quando possibile.
§ siamo preoccupati per i valori qui, quindi il fatto che i due presenti siano sempre due diversi oggetti fisici non è un'obiezione valida; se non sei convinto mi dispiace, non è questo il posto per spiegare la differenza tra valore e semantica "oggetto" (Algebra relazionale ha semantica valore dall'inizio - vedi il principio informativo di Codd; penso che alcuni implementatori di SQL DBMS don ti interessa anche una semantica comune).
§§ a mia conoscenza, questo è un assioma accettato (in una forma o nell'altra, ma sempre interpretato in un 2VL) fin dall'antichità e esattamente perché è così intuitivo. 3VLs (in realtà è una famiglia di logiche) è uno sviluppo molto più recente (ma non sono sicuro di quando sia stato sviluppato per la prima volta).
Nota a margine: se qualcuno introdurrà i tipi Bottom , Unit e Option come tentativi di giustificare i NULL SQL, sarò convinto solo dopo un esame abbastanza dettagliato che mostrerà come le implementazioni SQL con i NULL abbiano un sistema di tipi sonori e chiarirà, infine, cosa sono realmente i NULL (questi "valori-non-piuttosto-valori").
Di seguito citerò alcuni autori. Qualsiasi errore o omissione è probabilmente mio e non degli autori originali.
Joe Celko su SQL NULLs
Vedo Joe Celko spesso citato su questo forum. Apparentemente è un autore molto rispettato qui. Quindi, mi sono detto: "che cosa ha scritto sui NULL SQL? Come spiega i numerosi problemi dei NULL?". Uno dei miei amici ha una versione ebook dell'SQL di Joe Celko per gli smarties: programmazione SQL avanzata, 3a edizione . Vediamo.
Innanzitutto, il sommario. La cosa che mi colpisce di più è il numero di volte in cui viene menzionato NULL e nei contesti più svariati:
3.4 Aritmetica e NULL 109
3.5 Conversione di valori da e verso NULL 110
3.5.1 Funzione NULLIF () 110
6 NULL: dati mancanti in SQL 185
6.4 Confronto di NULL 190
6.5 NULL e logica 190
6.5.1 NULL nei predicati di sottoquery 191
6.5.2 Standard SQL Solutions 193
6.6 Math e NULL 193
6.7 Funzioni e NULL 193
6.8 NULL e lingue host 194
6.9 Consigli di progettazione per NULL 195
6.9.1 Evitare NULL dai programmi host 197
6.10 Una nota su più valori NULL 198
10.1 Predicato IS NULL 241
10.1. 1 Fonti di NULL 242
...
e così via. Mi suona "un brutto caso speciale".
Esaminerò alcuni di questi casi con estratti di questo libro, cercando di limitarmi all'essenziale, per motivi di copyright. Penso che queste citazioni rientrino nella dottrina del "fair use" e possano persino stimolare l'acquisto del libro - quindi spero che nessuno si lamenterà (altrimenti dovrò cancellarne la maggior parte, se non tutte). Inoltre, mi asterrò dal segnalare frammenti di codice per lo stesso motivo. Mi dispiace per quello. Acquista il libro per leggere il ragionamento basato sui dati.
I numeri di pagina tra parentesi in quanto segue.
Vincolo NOT NULL (11)
Il vincolo di colonna più importante è NOT NULL, che proibisce l'uso di NULL in una colonna. Usa questo vincolo di routine e rimuovilo solo quando hai buone ragioni. Ti aiuterà a evitare le complicazioni dei valori NULL quando esegui query sui dati.
Non è un valore ; è un marcatore che detiene un posto dove potrebbe andare un valore.
Ancora una volta questa assurdità "di valore ma non proprio di valore". Il resto mi sembra abbastanza sensato.
(12)
In breve, i NULL causano molte funzionalità irregolari in SQL, di cui parleremo più avanti. La tua scommessa migliore è solo quella di memorizzare le situazioni e le regole per i NULL quando non puoi evitarli.
A proposito di SQL, NULL e infinito:
(104) CAPITOLO 3: DATI NUMERICI IN SQL
SQL non ha accettato il modello IEEE per la matematica per diversi motivi.
...
Se le regole IEEE per la matematica fossero consentite in SQL, avremmo bisogno di digitare le regole di conversione per infinito e un modo per rappresentare un valore numerico esatto infinito dopo la conversione. Le persone hanno abbastanza problemi con i NULL, quindi non andiamo lì.
Implementazioni SQL indecise su cosa significhi davvero NULL in contesti particolari:
3.6.2 Funzioni esponenziali (116)
Il problema è che i logaritmi non sono definiti quando (x <= 0). Alcune implementazioni SQL restituiscono un messaggio di errore, alcune restituiscono un NULL e DB2 / 400; la versione 3 rilascio 1 ha restituito * NEGINF (abbreviazione di "infinito negativo") come risultato.
Joe Celko cita David McGoveran e CJ Date:
6 NULL: dati mancanti in SQL (185)
Nel loro libro A Guide to Sybase e SQL Server , David McGoveran e CJ Date hanno dichiarato: “È opinione di questo scrittore che i NULL, almeno come attualmente definiti e implementati in SQL, siano molto più problematici di quanto valgono e dovrebbero essere evitati; mostrano un comportamento molto strano e incoerente e possono essere una ricca fonte di errore e confusione. (Si noti che questi commenti e critiche si applicano a qualsiasi sistema che supporti NULL in stile SQL, non solo a SQL Server in particolare.) "
NULL come tossicodipendenza :
(186/187)
Nel resto di questo libro, ti esorto a non usarli , il che può sembrare contraddittorio, ma non lo è. Pensa a un NULL come a una droga; usalo correttamente e funziona per te, ma abusalo e può rovinare tutto. La tua migliore politica è di evitare i NULL quando puoi e di usarli correttamente quando devi.
La mia unica obiezione qui è "usarli correttamente", che interagisce male con comportamenti di implementazione specifici.
6.5.1 NULL nei predicati della sottoquery (191/192)
Le persone dimenticano che una sottoquery spesso nasconde un confronto con un NULL. Considera queste due tabelle:
...
Il risultato sarà vuoto. Questo è controintuitivo , ma corretto.
(separatore)
6.5.2 Soluzioni SQL standard (193)
SQL-92 ha risolto alcuni dei problemi di 3VL (logica a tre valori) aggiungendo un nuovo predicato del modulo:
<condizione di ricerca> È [NON] VERO | FALSO | SCONOSCIUTO
Ma SCONOSCIUTO è una fonte di problemi in sé, quindi CJ Date, nel suo libro citato di seguito, lo consiglio nel capitolo 4.5. Evitare i null in SQL :
- Non utilizzare la parola chiave SCONOSCIUTA in nessun contesto.
Leggi "DA PARTE" su SCONOSCIUTO, anch'esso collegato di seguito.
6.8 NULL e lingue host (194)
Tuttavia, è necessario sapere come vengono gestiti i NULL quando devono essere passati a un programma host. Nessuna lingua host standard per la quale è definito un incorporamento supporta i NULL, che è un'altra buona ragione per evitare di usarli nello schema del database.
(separatore)
6.9 Consigli di progettazione per NULL (195)
È consigliabile dichiarare tutte le tabelle di base con vincoli NOT NULL su tutte le colonne quando possibile. I NULL confondono le persone che non conoscono SQL e i NULL sono costosi.
Obiezione: i NULL confondono anche le persone che conoscono bene SQL, vedi sotto.
(195)
I NULL dovrebbero essere evitati nei TASTI ESTERI. SQL consente questa relazione "beneficio del dubbio", ma può causare una perdita di informazioni nelle query che coinvolgono join. Ad esempio, dato un codice del numero di parte nell'inventario a cui viene fatto riferimento come CHIAVE ESTERA da una tabella Ordini, si verificheranno problemi nell'ottenere un elenco delle parti che hanno un valore NULL. Questa è una relazione obbligatoria; non è possibile ordinare una parte che non esiste.
(separatore)
6.9.1 Evitare NULL dai programmi host (197)
È possibile evitare di inserire NULL nel database dai programmi host con una certa disciplina di programmazione.
...
- Determinare l'impatto dei dati mancanti sulla programmazione e sul reporting: le
colonne numeriche con NULL rappresentano un problema, poiché le query che utilizzano funzioni aggregate possono fornire risultati fuorvianti.
(separatore)
(227)
SUM () di un set vuoto è sempre NULL. Uno degli errori di programmazione più comuni commessi durante l'utilizzo di questo trucco è quello di scrivere una query che potrebbe restituire più di una riga. Se non ci pensassi, potresti aver scritto l'ultimo esempio come: ...
(separatore)
10.1.1 Fonti di NULL (242)
È importante ricordare dove possono verificarsi NULL. Sono più di un semplice valore in una colonna . Le funzioni aggregate su insiemi vuoti, OUTER JOIN, espressioni aritmetiche con NULL e operatori OLAP restituiscono tutti NULL. Questi costrutti si presentano spesso come colonne in VISUALIZZAZIONI.
(separatore)
(301)
Un altro problema con i NULL si trova quando si tenta di convertire i predicati IN in predicati EXISTS.
(separatore)
16.3 Le funzioni ALL Predicate ed Extrema (313)
All'inizio è controintuitivo che questi due predicati non siano gli stessi in SQL:
...
Ma devi ricordare le regole per le funzioni extrema: eliminano tutti i NULL prima di restituire i valori maggiori o minimi. Il predicato ALL non elimina i NULL, quindi è possibile ottenerli nei risultati.
(separatore)
(315)
Tuttavia, la definizione nello standard è formulata in negativo, in modo che i NULL ottengano il beneficio del dubbio. ...
Come puoi vedere, è una buona idea evitare NULL nei vincoli UNIQUE.
Discussing GROUP BY:
I NULL vengono considerati come se fossero tutti uguali tra loro e formano il proprio gruppo. Ogni gruppo viene quindi ridotto a una singola riga in una nuova tabella dei risultati che sostituisce quella precedente.
Ciò significa che per la clausola GROUP BY NULL = NULL non viene valutato come NULL, come in 3VL, ma viene valutato come TRUE.
Lo standard SQL è confuso:
The ORDER BY e NULLs (329)
Se un valore chiave di ordinamento NULL è considerato maggiore o minore di un valore non NULL è definito dall'implementazione, ma ...
... Ci sono prodotti SQL che lo fanno in entrambi i modi.
Nel marzo 1999, Chris Farrar ha sollevato una domanda di uno dei suoi sviluppatori che gli ha fatto esaminare una parte dello standard SQL che pensavo di aver capito . Chris ha riscontrato alcune differenze tra la comprensione generale e la formulazione effettiva delle specifiche .
E così via. Penso che sia abbastanza per Celko.
Data CJ su NULL SQL
CJ Date è più radicale sui NULL: evitare i NULL in SQL, punto. In effetti, il capitolo 4 della sua teoria SQL e relazionale: come scrivere un codice SQL accurato si intitola "NO DUPLICATES, NO NULLS", con i sottocapitoli
"4.4 Cosa c'è di sbagliato in Nulls?" e "4.5 Come evitare i null in SQL" (segui il link: grazie a Google Libri, puoi leggere alcune pagine online).
Fabian Pascal su SQL NULLs
Dai suoi problemi pratici nella gestione del database - Un riferimento per il professionista del pensiero (nessun estratto online, mi dispiace):
10.3 Implicazioni pratiche
10.3.1 NULL SQL
... SQL soffre dei problemi inerenti a 3VL, nonché di molte stranezze, complicazioni, controintuitività ed errori reali [10, 11]; tra questi ci sono i seguenti:
- Le funzioni aggregate (ad es. SUM (), AVG ()) ignorano i NULL (tranne COUNT ()).
- Un'espressione scalare su una tabella senza righe viene erroneamente valutata su NULL, anziché su 0.
- L'espressione "NULL = NULL" restituisce NULL, ma in realtà non è valida in SQL; tuttavia ORDER BY considera NULL uguali (qualunque cosa precedano o seguano valori "normali" è lasciato al fornitore DBMS).
- L'espressione "x IS NOT NULL" non è uguale a "NOT (x IS NULL)", come nel caso di 2VL.
...
Tutti i dialetti SQL implementati commercialmente seguono questo approccio 3VL e, quindi, non solo presentano questi problemi, ma hanno anche problemi di implementazione specifici, che variano tra i prodotti .