it-swarm.it

Quando utilizzare NULL e quando utilizzare una stringa vuota?

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?
    • Qualsiasi altro modo?
87
Maniero

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!

67
Larry Coleman

Non conosco MySQL e PostgreSQL, ma fammi trattare 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;

rendimenti 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 esempio 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 impostazioni predefinite vuote per loro. Quando riesci a distinguere tra '' e NULL sei in grado di esprimere che l'impostazione è vuota ed evitare che si applichi il valore predefinito.

26
bernd_k

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

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

17
Gan

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.

10

Potresti anche prendere in considerazione la critica di Date a NULL e i problemi di 3VL in SQL and Relational Theory (e la critica di Rubinson alla critica di Date, Nulls, Three-Valued Logic e Ambiguity in SQL: Critica della data della critica ).

Entrambi sono citati e discussi a lungo in un relativo SO, Opzioni per eliminare le colonne NULLable da un modello DB .

6
Abie

Un nuovo pensiero, una grande influenza sulla scelta di NULL/NOT NULL se si utilizza un framework. Uso molto symfony e l'utilizzo dei campi NULL 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 INSERT istruzioni non sia noioso dimenticando di impostare i campi vuoti su NULL.

4
Patrick

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 colonna NULLable che non consente zero-len '' (Soluzione Oracle-ish) o una colonna NOT NULL Che consente zero-len.

  • E dalla mia esperienza, '' Ha molto più più senso durante l'elaborazione dei dati, poiché normalmente si desidera elaborare l'assenza di un 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 usi '' Puoi semplicemente generare WHERE columnX = <searchvalue> E funzionerà per le ricerche sull'uguaglianza. Se usi NULL devi fare WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)

2
Martin

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

2
Guy Birkbeck

Se parliamo di teoria, allora le regole del Codd dicono che RDBMS deve trattare i valori di NULL 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.

1
noonex