NULL czy NOT NULL - o to jest pytanie

Przeglądając różne kody często widzę, iż programiści nie zwracają uwagi na to, czy ich pola są NULL czy NOT NULL. Ba, swego czasu mi to tam też było wsio rybka. Jednak jest to dość ważna kwestia.... No dobra, świat się przez nią nie skończy, ale dobrze jest na to zwracać uwagę.

Jeśli nie mamy jakiś konkretnych powodów by używać wartości NULL, zawsze ustawiajmy kolumnę jako NOT NULL. Jeśli w danej kolumnie nie ma znaczenia, czy wartością kolumny jest pusty tekst (lub 0 dla kolumn liczbowych) czy też NULL, znaczy że nie potrzebujecie wartości NULL i znowu należy oznaczyć kolumnę jako NOT NULL.

Po co to wszystko? Jest parę powodów.

  • Dla tabel MyISAM każda kolumna NULL zawiera dodatkowy bit extra (zaokrąglany w górę do najbliższego bajta)
  • Przejrzystsze wyszukiwania, np. gdy kolumna liczbowa może przyjmować NULL lub 0 dla określenia nie wypełnienia pola lub czegoś podobnego, musicie wówczas pamiętać w zapytaniu o tych dwóch wartościach. Gdy będziecie chcieli wyciągnąć rekordy o pustej kolumnie musicie pisać
    .... where KOLUMNA is null or KOLUMNA = 0
    Raz że czasem można o tym zapomnieć, dwa, że często przez to zapytania wykonują się wolniej. A jakby kolumna była NOT NULL to by wystarczyło
    .... where KOLUMNA = 0
  • Mniejsza wydajność (tak na prawdę więcej kombinacji) bazy przy pracy z indeksami założonymi na kolumnie z NULL ( dodane przez sowiq )
  • Ogólnie jest to dobra praktyka. Gdy programista zwraca na to uwagę to wiadomo, że wie co robi

Oczywiście kolumny typu NULL są jak najbardziej w niektórych przypadkach potrzebne i nie da się bez nich obejść. Starajmy się jednak zwracać uwagę, czy w danym przypadku na pewno jest to nam potrzebne. Rozważmy sytuację: mamy kolumnę liczbową, w której zapisywane są dane, które wpisywał użytkownik przez formularz. Użytkownik może podać wartości nieujemne lub nie wypełnić w ogóle pola. Wówczas wartość 0 nie oznacza pustej wartości, ale normalną wartość podaną przez użytkownika. Natomiast wartość NULL mogłaby oznaczać, że użytkownik nie wypełnił danego pola. Można by tu jednak zrobić inaczej. Skoro użytkownik może wprowadzić tylko nieujemne wartości, to można przyjąć że wartość -1 oznaczać będzie niewypełnienie pola i pole oznaczyć jako NOT NULL. Sztuka dla sztuki? Być może

Komentarze

 

2014-04-22 21:43 gość_aleJaNieChceSiePodpisywac

Jeżeli user może wprowadzić tylko liczby nieujemne to wypadałoby dla kolumny dać unsigned int/tinyint (w zależności od potrzeb) i właśnie użyć w tym przypadku null jako default value dla nie wypełnionego pola

2014-04-23 07:52 nospor

Tak, zgadza się. Ale jeśli będą to małe liczby i nieużycie unsigned nie wpłynie na koniecznośc zwiększenia typu, to można zrobić jak zaproponowałem. Ale nie bez powodu przy tym przykładzie zadałem pytanie "Sztuka dla sztuki?"

2014-04-23 10:15 gość_sowiq

Ciekawy artykuł, jednak moim zdaniem nie opisuje najważniejszej rzeczy. NULL / NOT NULL to nie tylko różnica 1B na rekord. To przede wszystkim mniejsza wydajność (tak na prawdę: więcej kombinacji) bazy przy pracy z indeksami założonymi na takiej kolumnie. Jest to w miarę ładnie opisane tutaj: http://stackoverflow.com/questions/1106258/mysql-null-vs/12706491#12706491

Co do wstawiania "-1" dla pustych wartości to IMO jest to zły pomysł, bo tworzy tylko bałagan. "-1" nie jest równoważne z NULL i raczej nie powinno się stosować takich zamian. Bo co jest bardziej czytelne, a co może wprowadzać więcej zamieszania i przez to błędów?
1. Rok urodzenia: NULL
2. Rok urodzenia: -1

2014-04-23 10:28 nospor

Dzięki sowiq Pozwoliłem sobie dodać twoją informaję do arta, z zaznaczeniem że od Ciebie. Mam nadzieję że się nie gniewasz.

Wiem, miałem mieszane uczucia odnośnie tego przykładu z -1. Nie mniej jednak napisałem że mozna dac null lub -1. Fakt, w niektorych przypadkach null bedzie zdecydowanie lepsze niz -1, nie mniej jednak raz czy dwa spotkalem się z sytuacją, gdzie -1 było jak najbardziej ok. Nie pamietam teraz dokładnie o co chodziło, ale wiem, iż z powodzeniem było to używane, dlatego też pozwoliłem sobie na taki przykład.

NULL na 100% jest nieodzowny w sytuacjach gdy mamy relacje i tabele InnoDB. W takim przypadku nie da się ustawić 0 dla nieokreślonych wartości (kluczy obcnych) - musi być NULL.

2014-06-14 21:29 gość_hyh

Można jeszcze wspomnieć o sortowaniu, w przypadku gdy kolumna zawiera NULL można zdefiniować czy ma być na początku czy końcu poprzez nulls last i nulls first.

2014-09-19 12:27 gość_Daimos

No proszę, ostatnio też dopadł mnie ten problem.
Tragedia jak ktoś nie usystematyzuje tego od razu i jak się programiści dorwą, mamy wartości NULL, puste, a i dodatkowo zero, jeszcze jakby do tego dodać -1 to już w ogóle byłaby choinka Trzy wartości do sprawdzania, to już przesada. Ale NULL mimo wydajności jest dla mnie świetne, ze względu na przejrzystość danych.

2014-09-19 19:26 nospor

Poruszyłeś ważny wątek: niezależnie co się wybierze, to należy się tego trzymać i nie robić potem burdelu ze to sprawdzenia pustej wartosci musimy użyć aż 3 warunków. Pod tym względem wywalenie NULL ma plusa, bo już tylko w najgorszym wypadku pozostaną do sprawdzenia 2 warunki

2015-05-16 22:19 gość_Bartek

Ciekawy i treściwy artykuł. Zresztą nie tylko ten powyższy. Dzięki za ten wpis. Trafiłem na Twój blog całkiem niedawno i szkoda że przestałeś "pisać". Jednak mam nadzieję że się to zmieni bo szkoda byłoby aby stracił na wartości.
Pozdrawiam
Bartek

Dodaj komentarz

 

Dostępne bbcode: b, u, i, url, code, php, css, html, sql, js

Ostatnio komentowane

  1. ShoutBox nospor
  2. ShoutBox Rafał
  3. ShoutBox nospor
  4. ShoutBox Rafał
  5. ShoutBox nospor
  6. ShoutBox Artur
  7. PHP South Coast conf... nospor

Ostatnio na forum

  1. backend developer or... adrian piwowarczyk
  2. PHP & JavaScript Dev... nofluffjobs
  3. https://www.internat... Ewa Miłkowska
  4. PHP & JS Developer @... nofluffjobs
  5. PHP & JS Developer @... nofluffjobs
  6. Full Stack PHP Devel... nofluffjobs
  7. Prośba o wytłumaczen... nospor

Skrypty użytkowników

  1. Klasa obsługi szablo... Lirdoner
  2. Sekcje user76
  3. Klasa walidująca for... user76
  4. Licznik Gości online korey
  5. Form Builder Comandeer
  6. Dynamiczny licznik z... korey
  7. Captcha Comandeer