Quando utilizzare NULL e quando utilizzare una stringa vuota?


82

Sono interessato principalmente a MySQL e PostgreSQL, ma potresti rispondere a quanto segue in generale:

  • Esiste uno scenario logico in cui sarebbe utile distinguere una stringa vuota da NULL?
  • Quali sarebbero le implicazioni dell'archiviazione fisica per l'archiviazione di una stringa vuota come ...

    • NULLO?
    • Stringa vuota?
    • Un altro campo?
    • Ogni altro modo?

Risposte:


67

Diciamo che il record proviene da un modulo per raccogliere informazioni su nome e indirizzo. La riga 2 dell'indirizzo sarà in genere vuota se l'utente non vive in appartamento. Una stringa vuota in questo caso è perfettamente valida. Tendo a preferire usare NULL per indicare che il valore è sconosciuto o non dato.

Non credo che valga la pena preoccuparsi della differenza di memoria fisica in pratica. Come amministratori di database, abbiamo pesci molto più grandi da friggere!


2
+1 pochissimi dba devono mai preoccuparsi delle differenze di velocità / dimensioni dell'uso NULLo no
Patrick

28
D'accordo ... Cerco di riservare NULL per "non noto" ... la stringa vuota è "sappiamo che dovrebbe essere vuota". È particolarmente utile quando i tuoi dati provengono da più fonti
Joe

6
Eccezionale - NULL non noto, è stata specificata la stringa vuota.
ScottCher

@Larry qual è l'impatto sulle prestazioni? In che modo le prestazioni variano con le tabelle di molte colonne rispetto alle tabelle di molte righe?
Shimmy,

Concordo sul fatto che se esiste una distinzione tra nessun valore fornito e una stringa vuota nel set di dati, è necessario utilizzarli in modo appropriato, ma personalmente se non ho bisogno di tale distinzione con i miei dati, utilizzo sempre una stringa vuota, semplicemente perché trova che il risultato della query da un client MySQL sulla riga di comando può essere più pulito da guardare con stringhe vuote invece di molti NULL
RTF

25

Non conosco MySQL e PostgreSQL, ma vorrei trattarlo un po 'in generale.

Esiste un DBMS, ovvero Oracle, che non consente di scegliere gli utenti tra NULL e ''. Ciò dimostra chiaramente che non è necessario distinguere tra entrambi. Ci sono alcune fastidiose conseguenze:

Si imposta varchar2 su una stringa vuota come questa:

Update mytable set varchar_col = '';

quanto segue porta allo stesso risultato

Update mytable set varchar_col = NULL;

Ma per selezionare le colonne in cui il valore è vuoto o NULL, devi usare

select * from mytable where varchar_col is NULL;

utilizzando

select * from mytable where varchar_col = '';

è sintatticamente corretto, ma non restituisce mai una riga.

Dall'altro lato, quando si concatenano le stringhe in Oracle. I varchar NULL vengono trattati come stringhe vuote.

select NULL || 'abc' from DUAL;

cede abc . Altri DBMS restituirebbero NULL in questi casi.

Quando vuoi esprimere esplicitamente che un valore è assegnato, devi usare qualcosa come ''.

E devi preoccuparti se il taglio non vuoti provoca NULL

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

Lo fa.

Ora guardiamo DBMS dove '' non è identico a NULL (ad es. SQL Server)

Lavorare con "" è generalmente più semplice e nella maggior parte dei casi non è necessario distinguere tra entrambi. Una delle eccezioni che conosco è quando la tua colonna rappresenta alcune impostazioni e non hai valori predefiniti vuoti per loro. Quando puoi distinguere tra '' e NULL sei in grado di esprimere che l'impostazione è vuota ed evitare che si applichi il valore predefinito.



17

Dipende dal dominio su cui stai lavorando. NULLsignifica assenza di valore (ovvero non esiste alcun valore ), mentre stringa vuota significa che esiste un valore di stringa di lunghezza zero.

Ad esempio, supponiamo che tu abbia una tabella per archiviare i dati di una persona e che contenga una Gendercolonna. È possibile salvare i valori come "Maschio" o "Femmina". Se l'utente è in grado di scegliere di non fornire i dati di genere, è necessario salvarli come NULL(ovvero l'utente non ha fornito il valore) e non una stringa vuota (poiché non esiste un genere con valore '').


7
Se l'utente ha scelto di non fornire un genere, sicuramente dovresti memorizzare "Rifiutato di fornire". NULL è ambiguo; potrebbe anche significare "non è stato chiesto al cliente", "il cliente si identifica con un genere non presente nella nostra lista", ecc.
Jon of All Trades

9

Una cosa da tenere a mente è che quando si dispone di un campo che non è richiesto, ma tutti i valori presenti devono essere univoci, è necessario memorizzare valori vuoti come NULL. Altrimenti, sarai in grado di avere solo una tupla con un valore vuoto in quel campo.

Ci sono anche alcune differenze con l'algebra relazionale e i valori NULL: NULL! = NULL, per esempio.


4
In realtà non è il caso che NULL! = NULL, perché è NULL. ;-)
Peter Eisentraut il

1
Si noti che MS SQL non segue questa regola: più valori NULL violeranno un UNIQUEvincolo. Fortunatamente, a partire dal 2008 è possibile utilizzare un indice filtrato per ottenere il comportamento corretto.
Jon of All Trades


4

Un nuovo pensiero, una grande influenza sulla tua scelta di NULL/ NOT NULLè se stai usando un framework. Uso molto symfony e l'uso dei NULLcampi consentiti semplifica la verifica del codice e dei dati durante la manipolazione dei dati.

Se non si utilizza un framework o se si utilizzano semplici istruzioni ed elaborazioni sql, sceglierei qualsiasi scelta riteniate sia più semplice da tenere traccia. In genere preferisco NULL in modo che fare INSERTdichiarazioni non diventi noioso dimenticando di impostare i campi vuoti su NULL.


la domanda riguarda NULL vs. stringa vuota (in una colonna nullable, IMO), non NULL vs NOT NULL, vero?
Gan

la parte della domanda sull'archiviazione mi ha portato a pensare che potrebbe pensare anche a Null / Not Null
Patrick

o @ogni altro riguardo all'implicazione di NULL vs NOT NULL, puoi fare riferimento a questo: dba.stackexchange.com/q/63/107
Gan

2

Avendo dovuto lavorare con Oracle ( che non ti consente di differenziare ) sono giunto alla seguente conclusione:

  • Da un POV logico non importa. Non riesco davvero a pensare a un esempio convincente in cui la differenziazione tra NULL e stringa di lunghezza zero aggiunge alcun valore nel DBMS.

  • Da cui segue: O hai una NULLcolonna in grado che non consente zero-len ''(soluzione Oracle-ish) o una NOT NULLcolonna che consente zero-len.

  • E dalla mia esperienza, ''ha molto più senso quando si elaborano i dati, poiché normalmente si desidera elaborare l'assenza di una stringa come stringa vuota: concatenazione, confronto, ecc.

Nota: per tornare alla mia esperienza Oracle: supponi di voler generare una query per una richiesta di ricerca. Se lo usi ''puoi semplicemente generare WHERE columnX = <searchvalue>e funzionerà per le ricerche sull'uguaglianza. Se usi NULLdevi farlo WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)


2

Sono anche diversi dal punto di vista del design:

per esempio

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

Sembra:

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

Consente di inserire alcuni dati:

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

Ora proviamo con null:

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

Questo è permesso

Soooooo: i null non sono stringhe banali né il contrario.

Saluti


1

Se parliamo di teoria, allora le regole del Codd dicono che RDBMS deve trattare i NULLvalori in un modo speciale.

Il modo esatto in cui viene utilizzato dipende dagli architetti del database, a seconda dell'effettivo dominio - attività - progetto - area di applicazione.

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.