it-swarm.dev

Kiedy używać NULL, a kiedy używać pustego ciągu?

Interesuję się głównie MySQL i PostgreSQL, ale ogólnie możesz odpowiedzieć na następujące pytania:

  • Czy istnieje logiczny scenariusz, w którym przydatne byłoby odróżnienie pustego ciągu od NULL?
  • Jakie byłyby implikacje fizycznego przechowywania dla przechowywania pustego ciągu jako ...

    • ZERO?
    • Pusta struna?
    • Kolejne pole?
    • W jakikolwiek inny sposób?
87
Maniero

Powiedzmy, że rekord pochodzi z formularza służącego do gromadzenia informacji o nazwie i adresie. Wiersz 2 adresu będzie zwykle pusty, jeśli użytkownik nie mieszka w mieszkaniu. Pusty ciąg w tym przypadku jest całkowicie poprawny. Wolę używać NULL, aby oznaczać, że wartość jest nieznana lub nie została podana.

Nie sądzę, że w praktyce warto martwić się różnicą w fizycznym przechowywaniu. Jako administratorzy baz danych mamy znacznie większe ryby do smażenia!

67
Larry Coleman

Nie wiem o MySQL i PostgreSQL, ale pozwól mi potraktować to trochę ogólnie.

Jest jeden DBMS, a mianowicie Oracle, który nie pozwala wybrać użytkowników pomiędzy NULL a „”. To wyraźnie pokazuje, że nie jest konieczne rozróżnienie między nimi. Istnieją pewne irytujące konsekwencje:

Ustawiasz varchar2 na pusty ciąg taki jak ten:

Update mytable set varchar_col = '';

następujące prowadzi do tego samego wyniku

Update mytable set varchar_col = NULL;

Ale aby wybrać kolumny, w których wartość jest pusta lub NULL, musisz użyć

select * from mytable where varchar_col is NULL;

Za pomocą

select * from mytable where varchar_col = '';

jest poprawny pod względem składniowym, ale nigdy nie zwraca wiersza.

Z drugiej strony, podczas łączenia łańcuchów w Oracle. Warchary NULL są traktowane jako puste ciągi.

select NULL || 'abc' from DUAL;

daje abc. W innych przypadkach DBMS zwróciłoby wartość NULL.

Jeśli chcesz wyraźnie wyrazić, że wartość jest przypisana, musisz użyć czegoś takiego jak ''.

I musisz się martwić, czy przycinanie niepustych wyników daje NULL

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

To robi.

Teraz patrząc na DBMS, gdzie „” nie jest identyczne z NULL (np. SQL-Server)

Praca z „” jest na ogół łatwiejsza iw większości przypadków nie ma praktycznej potrzeby rozróżnienia między nimi. Jednym z wyjątków, jaki znam, jest sytuacja, w której kolumna reprezentuje jakieś ustawienie i nie ma dla nich pustych ustawień domyślnych. Kiedy możesz rozróżnić „” i „NULL”, możesz wyrazić, że twoje ustawienie jest puste i uniknąć domyślnego ustawienia.

26
bernd_k

To zależy od domeny, nad którą pracujesz. NULL oznacza brak wartości (tzn. nie ma żadnej wartości ), podczas gdy pusty ciąg oznacza, że ​​jest wartość ciągu o zerowej długości.

Załóżmy na przykład, że masz tabelę do przechowywania danych osoby i zawiera ona kolumnę Gender. Możesz zapisać wartości jako „Mężczyzna” lub „Kobieta”. Jeśli użytkownik może zdecydować się nie podawać danych dotyczących płci, należy zapisać to jako NULL (tj. Użytkownik nie podał wartości) i nie pusty ciąg znaków (ponieważ nie ma płeć z wartością '').

17
Gan

Jedną z rzeczy, o których warto pamiętać, jest to, że gdy masz pole, które nie jest wymagane, ale wszystkie obecne wartości muszą być unikalne, będą wymagały przechowywania pustych wartości jako NULL. W przeciwnym razie będziesz mieć tylko jedną krotkę z pustą wartością w tym polu.

Istnieją również pewne różnice w algebrze relacyjnej i wartościach NULL: na przykład NULL! = NULL.

10

Możesz również uwzględnić krytykę NULL dla Daty i problemy 3VL w Teoria relacyjna i SQL (i krytyka Rubinsona dla krytyki Daty, Nulls, trójwartościowa logika i niejednoznaczność w SQL: Krytyka daty krytyki ).

Oba są przywoływane i omawiane szczegółowo w pokrewnym SO, Opcje usuwania kolumn NULLable z modelu DB .

6
Abie

Nowa myśl, duży wpływ na wybór NULL/NOT NULL jest, jeśli używasz frameworka. Używam dużo symfony i użycie pól NULL upraszcza sprawdzanie kodu i danych podczas manipulowania danymi.

Jeśli nie używasz frameworka lub używasz prostych instrukcji SQL i przetwarzania, wybrałbym wybór, który Twoim zdaniem jest łatwiejszy do śledzenia. Zazwyczaj wolę NULL, aby wykonywanie instrukcji INSERT nie nudziło się, gdy zapomniałem ustawić puste pola na NULL.

4
Patrick

Musiałem współpracować z Oracle ( co nie pozwala na rozróżnienie ) Doszedłem do następującego wniosku:

  • Z logicznego POV to nie ma znaczenia. Naprawdę nie mogę wymyślić przekonującego przykładu, w którym rozróżnienie między NULL a ciągiem o zerowej długości dodaje jakąkolwiek wartość w DBMS.

  • Z tego wynika, że: albo masz kolumnę NULLable, która nie pozwala na zero-len '' (Rozwiązanie Oracle) lub kolumnę NOT NULL, Która pozwala na zero-len.

  • Z mojego doświadczenia wynika, że ​​'' Sprawia, że ​​ dużo ma więcej sensu podczas przetwarzania danych, ponieważ normalnie chciałbyś przetwarzać brak ciąg jako pusty ciąg: konkatenacja, porównanie itp.

Uwaga: Aby wrócić do mojego doświadczenia z Oracle: Powiedz, że chcesz wygenerować zapytanie dotyczące żądania wyszukiwania. Jeśli użyjesz '', Możesz po prostu wygenerować WHERE columnX = <searchvalue> I będzie działać dla wyszukiwania równości. Jeśli używasz NULL musisz zrobić WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)

2
Martin

Różnią się także od perspektywy projektowania:

na przykład.

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

CREATE UNIQUE INDEX t_AK1 ON t (name);

Wygląda jak:

 \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)

Pozwala wstawić niektóre dane:

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"

Teraz spróbujmy z zerowym:

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

INSERT 0 1

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

INSERT 0 1

To jest dozwolone.

Soooooo: wartości null nie są trywialnymi łańcuchami ani odwrotnością.

Twoje zdrowie

2
Guy Birkbeck

Jeśli mówimy o teorii, wówczas reguły Codda mówią, że RDBMS musi traktować wartości NULL w specjalny sposób.

To, jak dokładnie to zostanie zastosowane, zależy od architektów baz danych, w zależności od faktycznej dziedziny - zadania - projektu - aplikacji - obszaru.

1
noonex