SQL: stringa vuota vs valore NULL

69

So che questo argomento è un po 'controverso e ci sono molti articoli / opinioni che galleggiano su Internet. Sfortunatamente, molti di loro presumono che la persona non sappia quale sia la differenza tra NULL e stringa vuota. Quindi raccontano storie di risultati sorprendenti con join / aggregati e generalmente eseguono lezioni SQL un po 'più avanzate. Facendo questo, perdono assolutamente il punto e sono quindi inutili per me. Quindi spero che questa domanda e tutte le risposte si sposteranno un po 'più avanti.

Supponiamo di avere una tabella con informazioni personali (nome, nascita, ecc.) in cui una delle colonne è un indirizzo email con tipo varchar. Supponiamo che per qualche motivo alcune persone potrebbero non voler fornire un indirizzo email. Quando si inseriscono tali dati (senza e-mail) nella tabella, ci sono due scelte disponibili: imposta la cella su NULL o imposta la stringa vuota (''). Supponiamo di essere a conoscenza di tutte le implicazioni tecniche della scelta di una soluzione rispetto a un'altra e di creare query SQL corrette per entrambi gli scenari. Il problema è anche quando entrambi i valori differiscono a livello tecnico, sono esattamente gli stessi a livello logico. Dopo aver osservato NULL e '' sono giunto a una conclusione: non conosco l'indirizzo email del ragazzo. Inoltre, non importa quanto sia stato difficile provarlo, non sono stato in grado di inviare una e-mail utilizzando NULL o una stringa vuota, quindi apparentemente la maggior parte dei server SMTP è d'accordo con la mia logica. Quindi tendo ad usare NULL dove non conosco il valore e considero la stringa vuota una cosa negativa.

Dopo alcune intense discussioni con i colleghi sono arrivato con due domande:

  1. ho ragione nel presumere che l'uso di una stringa vuota per un valore sconosciuto sta causando un "bugiardo" del database sui fatti? Per essere più precisi: usando l'idea di SQL di ciò che è valore e cosa non lo è, potrei arrivare alla conclusione: abbiamo un indirizzo e-mail, solo scoprendo che non è nullo. Ma più tardi, quando provo ad inviare e-mail, arriverò a conclusioni contraddittorie: no, non abbiamo un indirizzo e-mail, che @! # $ Database deve aver mentito!

  2. Esiste uno scenario logico in cui una stringa vuota "" potrebbe essere un buon vettore di informazioni importanti (oltre al valore e nessun valore), il che sarebbe problematico / inefficiente da memorizzare in qualsiasi altro modo (come ulteriore colonna). Ho visto molti post che affermano che a volte è bene usare una stringa vuota insieme a valori reali e valori NULL, ma finora non abbiamo visto uno scenario che sarebbe stato logico (in termini di progettazione SQL / DB).

P.S. Alcune persone saranno tentate di rispondere, che è solo una questione di gusto personale. Non sono d'accordo Per me è una decisione di progettazione con conseguenze importanti. Quindi mi piacerebbe vedere le risposte in cui un'opinione su questo è supportata da alcuni motivi logici e / o tecnici.

    
posta Jacek Prucia 30.12.2010 - 13:10
fonte

12 risposte

82

Direi che NULL è la scelta corretta per "nessun indirizzo email". Ci sono molti indirizzi email "non validi" e "" (stringa vuota) è solo uno. Ad esempio "foo" non è un indirizzo email valido, "a @ b @ c" non è valido e così via. Quindi, solo perché "" non è un indirizzo email valido non c'è motivo di usarlo come valore "nessun indirizzo email".

Penso che tu abbia ragione nel dire che "" non è il modo corretto per dire "Non ho un valore per questa colonna". "" è un valore.

Un esempio di dove "" potrebbe essere un valore valido, separato da NULL potrebbe essere il secondo nome di una persona. Non tutti hanno un secondo nome, quindi è necessario distinguere tra "nessun secondo nome" ("" - stringa vuota) e "Non so se questa persona ha un secondo nome o no" ( NULL ). Ci sono probabilmente molti altri esempi in cui una stringa vuota è ancora un valore valido per una colonna.

    
risposta data 30.12.2010 - 13:22
fonte
41

Pur condividendo i suddetti commenti, aggiungerei questo argomento come motivazione primaria:

  1. È ovvio per qualsiasi programmatore che osserva un database che un campo contrassegnato NULL è un campo facoltativo. (cioè il record non richiede dati per quella colonna)
  2. Se contrassegni un campo NOT NULL, qualsiasi programmatore dovrebbe presumere intuitivamente che si tratta di un campo obbligatorio.
  3. In un campo che consente i valori null, i programmatori dovrebbero aspettarsi di vedere i valori nulli anziché le stringhe vuote.

Per motivi di codifica intuitiva autodocumentazione, usa NULL invece di stringhe vuote.

    
risposta data 14.09.2011 - 23:30
fonte
6

Nel tuo esempio, se è valore direttamente dal campo web, userei la stringa vuota. Se l'utente ha la possibilità di specificare che non desidera fornire email, o potrebbe eliminarlo, allora NULL.

Ecco il link con i punti che potresti prendere in considerazione: link

--- modificato (in risposta al commento di Thomas) ---

I database non vivono senza applicazioni che li utilizzano. La definizione di NULL o '' non ha valore, se l'applicazione non può usarla correttamente.

Considera un esempio in cui l'utente sta compilando il modulo LONG e premi invio, che invierà la richiesta persistente al server. Potrebbe essere nel mezzo di inserire la sua email. Molto probabilmente vuoi archiviare tutto ciò che ha nel campo della posta elettronica, quindi più tardi potrebbe terminarlo. E se avesse inserito un solo personaggio? Cosa succede se ha inserito un carattere e poi cancellarlo? Quando l'e-mail non è richiesta, a volte gli utenti vogliono eliminarlo: il modo più semplice per cancellare il campo. Anche nel caso in cui l'e-mail non sia richiesta, vale la pena di convalidarla prima dell'invio.

Un altro esempio: l'utente fornisce email come spam @ [bigcompany] .com - in tal caso non è necessario inviare e-mail, anche se è esistente e valida (e potrebbe persino esistere). L'invio di uno di questi può essere economico, ma se ci sono utenti 10K con email di questo tipo per gli abbonamenti giornalieri, la convalida potrebbe comportare un notevole risparmio di tempo.

    
risposta data 30.12.2010 - 13:41
fonte
4

Utilizza Null.

Non ha senso archiviare un valore di "", semplicemente facendo il campo nella tabella nullable. Rende le domande più ovvie anche.

Quale query SQL è più ovvia e leggibile se si desidera trovare utenti con un indirizzo email?

  1. SELECT * FROM Users WHERE email_address != ''

  2. SELECT * FROM Users WHERE email_address IS NOT NULL

  3. SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL

Direi 2 è. Sebbene 3 sia più robusto nei casi in cui sono memorizzati dati non validi.

Per il caso dell'indirizzo email sul modulo, che è opzionale, dovrebbe essere riportato anche nella tabella. In SQL, è un campo nullable, il che significa che non è noto.

Non riesco a pensare ad alcun valore commerciale ragionevole nell'archiviazione di una stringa vuota in una tabella diversa dalla semplice progettazione errata. È come memorizzare un valore di stringa di 'NULL' o 'BLANK', e con gli sviluppatori si assume che è null o una stringa vuota. Per me, è un cattivo design. Perché memorizzarlo quando c'è NULL ??

Utilizza NULL e renderai tutti più felici.

ULTERIORI INFORMAZIONI:

SQL utilizza un sistema logico a tre valori: True, False e Sconosciuto.

Per una spiegazione migliore e più dettagliata, consiglio agli sviluppatori di leggere: Query SQL - oltre VERO e FALSO .

    
risposta data 15.09.2011 - 00:17
fonte
4

Penso che la risposta di Dean Hardings lo copra davvero bene. Detto questo vorrei menzionare che quando si parla di NULL contro stringhe vuote a livello di DB, si dovrebbe riflettere sugli altri tipi di dati. Vuoi memorizzare una data minima quando non viene fornita alcuna data? o -1 quando non viene fornito alcun INT? Memorizzare un valore quando non hai alcun valore significa che devi quindi tenere traccia di un intero intervallo di non valori. Almeno uno per ogni tipo di dati (possibilmente più come si ottengono i casi in cui -1 è un valore effettivo quindi è necessario avere qualche alternativa ecc.). Se hai bisogno / vuoi fare qualcosa di "fudgy" a livello di applicazione è una cosa, ma non è necessario inquinare i tuoi dati.

    
risposta data 08.08.2012 - 11:18
fonte
3

per la specifica domanda tecnica, il problema non è null vs empty-string, è un errore di convalida . Una stringa vuota non è un indirizzo email valido!

per la domanda filosofica, la risposta è simile: conferma i tuoi input. Se una stringa vuota è un valore valido per il campo in questione, allora aspettalo e codice per esso; in caso contrario, usa null.

Una stringa vuota sarebbe un input valido per rispondere alla domanda: che cosa ha detto il mimo alla giraffa?

    
risposta data 30.12.2010 - 15:49
fonte
2

Potrei pensare a un motivo per avere NULL e la stringa vuota:

  • Hai indirizzi email validi: [email protected]
  • Non ne hai (e probabilmente dovresti chiederne uno): NULL
  • Sai che questa persona non ha un indirizzo email: Empty String.

Tuttavia, non lo consiglierei e userei un campo separato per chiedere se sai che nessuno è esistente.

    
risposta data 15.01.2013 - 16:43
fonte
1

La domanda, a quanto ho capito, è che le interpretazioni di NULL e stringa vuota dovrebbero essere scelte. Ciò dipende dal numero di stati in cui può trovarsi il campo particualar.

L'interpretazione dipende da come si accede al database. Se c'è un livello nel codice che estrae completamente il database, allora la scelta di qualsiasi criterio (incluso il two-coulmn) che funziona è completamente accettabile. (Tuttavia, documentare chiaramente la politica è importante). Tuttavia, se si accede al database in più punti, è necessario utilizzare uno schema molto semplice, poiché il codice sarà più difficile da mantenere e potrebbe essere errato in questo caso.

    
risposta data 30.12.2010 - 14:05
fonte
1

Fondamentalmente a livello logico non c'è differenza tra il valore "non valido" e "nessun input dell'utente", sono solo tutti "casi speciali" il più delle volte. Errore.

Avere null prende spazio addizionale: ceil (columns_with_null / 8) in byte / per riga.

Le celle vuote e null sono entrambi modi per contrassegnare che qualcosa è sbagliato / dovrebbe essere l'impostazione predefinita. Perché avresti bisogno di 2 stati "sbagliati"? Perché utilizzare NULL se occupano spazio aggiuntivo e significano esattamente le stringhe vuote? Ciò introdurrà solo confusione e ridondanza quando stai avendo due cose che significano (che potrebbe significare) esattamente la stessa cosa, è facile dimenticare che dovresti usare NULL invece di stringhe vuote (se per esempio l'utente ha omesso alcuni campi).

E i tuoi dati possono diventare un casino. In un mondo perfetto diresti "i dati saranno sempre corretti e me lo ricorderò" ... ma quando le persone devono lavorare in una squadra e non tutti sono esattamente al tuo livello, non è raro vedere WHERE (aa. xx < > '' AND bb.zz NON È NULL)

Quindi, invece di correggere i membri del mio team ogni due giorni, impongo semplicemente una semplice regola. Nessun valore null, MAI!

Il conteggio dei valori NON NULL è più veloce ... una domanda semplice è a cosa avresti bisogno per farlo?

    
risposta data 30.12.2010 - 15:35
fonte
1

Tendo a vederlo non dalla prospettiva del DB ma dal punto di vista del programma. So che questa domanda è per il clic SQL, ma in realtà, quanti utenti accedono direttamente ai dati più a lungo?

In un programma non mi piace null / nothing. Ci sono alcune eccezioni ma sono proprio questo. E quelle eccezioni sono solo cattive implementazioni.

Quindi, se l'utente non ha inserito l'e-mail, dovrebbe esserci qualcosa che determina se questo è valido o meno. Se un'e-mail vuota va bene, viene visualizzata una stringa vuota. Se l'utente non ha inserito un'email e questo viola una regola, l'oggetto dovrebbe indicarlo.

L'idea di avere un significato nullo è vecchia scuola ed è qualcosa che i programmatori moderni devono risolvere.

Anche nella progettazione del DB, perché il campo email non può consentire null e avere una stringa di lunghezza zero e avere un altro campo che indica se l'utente inserisce qualcosa? C'è un po 'di più da chiedere a un DBMS? Il DB non dovrebbe, a mio avviso, gestire né la logica aziendale né la logica di visualizzazione. Non è stato costruito per questo e quindi fa un lavoro molto scarso nel maneggiarlo.

    
risposta data 18.03.2011 - 05:48
fonte
-1

Non penso che importi molto, ma mi piace di più quando c'è il NULL.

Quando visualizzo i dati visualizzati in una tabella (come in SQL Server Management Studio), posso distinguere meglio un valore mancante se dice NULL e lo sfondo è di colore diverso.

Se vedo uno spazio vuoto, mi chiedo sempre se è veramente vuoto o ci sono spazi bianchi o alcuni caratteri invisibili. Con NULL è garantito vuoto a prima vista.

Di solito non distinguo i valori nell'applicazione, perché è inaspettato e strano che NULL e stringa vuota significhino qualcosa di diverso. E la maggior parte delle volte, prendo un approccio difensivo e mi occupo solo di entrambi gli stati. Ma per me come uomo, NULL è più facile da elaborare quando si guardano i dati.

    
risposta data 11.08.2016 - 16:54
fonte

Leggi altre domande sui tag