Pytanie Standardowe użycie "Z" zamiast NULL do reprezentowania brakujących danych?


Poza argumentem, czy NULL kiedykolwiek powinny być używane: Jestem odpowiedzialny za istniejącą bazę danych, która używa NULL do oznaczenia "brakujących lub nigdy nie wprowadzonych" danych. Różni się on od pustego łańcucha, co oznacza, że ​​"użytkownik ustawił tę wartość i wybrał" pusty "."

Inny wykonawca projektu jest mocno związany z "NULL nie istnieją dla mnie, nigdy nie używam NULL i nikt inny nie powinien," po stronie argumentu. Jednak, co jest mylące, to fakt, że zespół wykonawców DOES potwierdza różnicę między "brak / nigdy nie wprowadzono" i "celowo pusty lub wskazany przez użytkownika jako nieznany", używają pojedynczego znaku "Z" w całym kodzie i procedurach przechowywanych do reprezentuje "brakujący / nigdy nie wprowadzony" z tym samym znaczeniem co NULL w pozostałej części bazy danych.

Chociaż nasz wspólny klient poprosił o zmianę, a ja poparłem tę prośbę, zespół cytuje to jako "standardową praktykę" wśród administratorów DBA o wiele bardziej zaawansowaną niż ja; niechętnie się zmieniają, aby używać NULL na podstawie mojej nieświadomej prośby. Czy ktoś może mi pomóc pokonać moją niewiedzę? Czy istnieje jakaś standardowa lub mała grupa osób, a nawet pojedynczy głośny głos wśród ekspertów SQL, który opowiada się za użyciem "Z" zamiast NULL?

Aktualizacja

Mam odpowiedź od wykonawcy, aby dodać. Oto, co powiedział, gdy klient poprosił o usunięcie specjalnych wartości, aby zezwolić na NULL w kolumnach bez danych:

Zasadniczo zaprojektowałem bazę danych, aby w miarę możliwości unikać NULL. Oto uzasadnienie:

NULL w polu [VARCHAR] nie jest konieczne, ponieważ pusty łańcuch (o zerowej długości) dostarcza dokładnie te same informacje.

Wartość NULL w polu całkowitym (np. Wartość identyfikatora) może być obsługiwana przy użyciu wartości, która nigdy nie wystąpiłaby w danych (np. -1 dla pola IDENTYFIKACJA całkowitoliczbowa). 

Wartość NULL w polu daty może łatwo spowodować komplikacje w obliczeniach daty. Na przykład w logice obliczającej różnice między datami, takich jak różnica w dniach między [Data odzyskiwania] a datą włączenia, logika zostanie zwiększona, jeśli jedna lub obie daty mają wartość NULL, chyba że dla obu dat zostanie wprowadzony wyraźny margines jest NULL. To dodatkowa praca i dodatkowa obsługa. Jeśli daty "domyślne" lub "zastępcze" są używane dla [Data odzyskania] i [data włączenia] (np. "1/1/1900"), obliczenia matematyczne mogą pokazywać wartości "nietypowe", ale logika dat nie ulegnie awarii.

Obsługa NULL tradycyjnie była dziedziną, w której programiści popełniają błędy w procedurach przechowywanych. 

Przez 15 lat pracy jako DBA, najlepiej było unikać NULL, gdy tylko było to możliwe.

Wydaje się to potwierdzać najbardziej negatywną reakcję na to pytanie. Zamiast stosowania przyjętego podejścia 6NF do projektowania wartości NULL, specjalne wartości są używane do "unikania NULL, gdy tylko jest to możliwe". Postawiłem to pytanie z otwartym umysłem i cieszę się, że dowiedziałem się więcej na temat debaty "NULL są użyteczne / NULL są złe", ale teraz całkiem dobrze określam podejście "wartości specjalnych" jako kompletny nonsens.

pusty łańcuch o zerowej długości dostarcza dokładnie te same informacje.

Nie, nie ma; w istniejącej bazie danych modyfikujemy, NULL oznacza "nigdy nie wprowadzono", a pusty ciąg oznacza "wprowadzony jako pusty".

Obsługa NULL tradycyjnie była dziedziną, w której programiści popełniają błędy w procedurach przechowywanych.

Tak, ale te błędy zostały popełnione tysiące razy przez tysiące programistów, a lekcje i zastrzeżenia do uniknięcia tych błędów są znane i udokumentowane. Jak już wspomniano tutaj: czy akceptujesz lub odrzucasz NULL, reprezentacja brakujących wartości to rozwiązany problem. Nie ma potrzeby wynajdywania nowego rozwiązania tylko dlatego, że programiści kontynuują łatwe do przezwyciężenia (i łatwe do zidentyfikowania) błędy.


Jako przypis: byłem DBE i programistą od ponad 20 lat (co z pewnością jest wystarczającą porą, aby poznać różnicę między inżynierem bazy danych a administratorem bazy danych). Przez całą moją karierę zawsze byłem w obozie "NULL są użyteczne", choć zdawałem sobie sprawę, że kilku bardzo inteligentnych ludzi się nie zgadzało. Byłem bardzo sceptyczny w stosunku do podejścia "specjalnych wartości", ale nie byłem wystarczająco dobrze zorientowany w środowisku akademickim "Jak uniknąć NULL we właściwy sposób", aby stanowczo stawić czoła. Zawsze uwielbiam uczyć się nowych rzeczy - i wciąż mam dużo do nauczenia się po 20 latach. Dziękuję wszystkim, którzy przyczynili się do tego, że jest to przydatna dyskusja.


76
2017-07-09 23:59


pochodzenie


NULL istnieje, aby umożliwić logika trójwymiarowa co jest konieczne, aby zachować integralność referencyjną w przypadku braku kompletnych informacji - nazwałabym kompletne i całkowite BS na każdym ogłoszonym ekspercie DB, który jest zdecydowanie przeciwko nim! - gordy
Nigdy nie słyszałem o tej praktyce. - Calvin Allen
Czy wykonawca zaproponował również zastępczą wartość NULL dla danych liczbowych? - Andriy M
@Andriy: Łatwo to rozwiązać, wszyscy eksperci przechowują numery w polach postaci i odrzucają je (za pomocą Z-czeków!) W razie potrzeby. Zaczekaj, Jestem na niewłaściwej stronie. - mu is too short
Podejrzewam, że kiedyś ten wykonawca próbował wykonać WHERE Column = NULL i był zdezorientowany, dlaczego nie uzyskał żadnych wyników. - Mike Caron


Odpowiedzi:


Zwiąż swojego kontrahenta.

Okej, poważnie, to nie jest standardowa praktyka. Widać to po prostu dlatego, że wszystkie RDBMS, które kiedykolwiek pracowałem z implementacją NULL, logika dla NULL, biorą pod uwagę NULL w kluczach obcych, mają inne zachowanie dla NULL w COUNT itd., Itd.

W rzeczywistości twierdzę, że używanie "Z" lub jakiegokolwiek innego posiadacza miejsca jest gorsze. Nadal potrzebujesz kodu, aby sprawdzić "Z". Ale musisz również udokumentować, że "Z" nie oznacza "Z", to znaczy coś innego. I musisz upewnić się, że taka dokumentacja jest czytana. A co się stanie, jeśli "Z" stanie się kiedykolwiek ważnym plikiem danych? (Takich jak pole początkowe?)

Na poziomie podstawowym, nawet bez debaty na temat ważności NULL vs "Z", chciałbym nalegać, aby wykonawca był zgodny ze standardowymi praktykami, które istnieją w twojej firmie, a nie jego. Wprowadzenie standardowej praktyki w środowisku z alternatywną standardową praktyką spowoduje zamieszanie, koszty ogólne utrzymania, błędne zrozumienie, a na koniec zwiększone koszty i błędy.


EDYTOWAĆ

Zdarzają się przypadki, w których używanie alternatywy do NULL jest ważne w mojej opinii. Ale tylko tam, gdzie to zmniejsza kod, zamiast tworzyć specjalne przypadki, które wymagają rozliczenia.

Użyłem tego na przykład dla danych związanych z datą. Jeśli dane są ważne między datą początkową a datą końcową, kod można uprościć, nie mając wartości NULL. Zamiast tego NULL data początkowa może zostać zastąpiona przez "01.01.1900", a data NULL może zostać zastąpiona datą "31 grudnia 2079".

To nadal może zmienić zachowanie z tego, czego można się spodziewać, dlatego powinno być używane z ostrożnością:

  • WHERE end-date IS NULL nie daje już danych, które są nadal ważne
  • Właśnie stworzyłeś swój własny błąd milenijny
  • itp.

Jest to odpowiednik reformowania abstrakcji, tak że wszystkie właściwości mogą zawsze mieć prawidłowe wartości. Znacznie różni się od domyślnego kodowania określonego znaczenia do dowolnie wybranych wartości.

Mimo to zwolnij wykonawcę.


104
2017-07-10 00:13



+1 ode mnie; na miejscu: "Naprawdę twierdzę, że używanie" Z "lub jakiegokolwiek innego posiadacza miejsca jest gorsze. Nadal potrzebujesz kodu, aby sprawdzić" Z ", ale musisz również udokumentować, że" Z "nie oznacza" Z ", to znaczy coś innego. " - Mitch Wheat
Potrzebujemy specjalnej wartości - nie NULL, ponieważ NULL jest zła - do reprezentowania brakujących danych. Coś, co różni się od wszystkich innych wartości, może nawet od siebie (ponieważ dwóch niewiadomych nie można zrównoważyć tylko dlatego, że są one nieznane). Niektóre kolumny oczywiście nie miałyby sensu z tą wartością, więc powinno być zabronione. Aby było to łatwiejsze, potrzebowalibyśmy specjalnych operatorów, takich jak IS UNKNOWN lub IS NOT UNNNOWN. - Mike Caron
+1 - magiczne wartości są gorsze od NULL. - APC
Kontrahenci często mają dobre rady z głębokiego doświadczenia, ale tylko dlatego czasami zdarza się, nie znaczy, że musisz podążać za owcami ponad zalecanym niebezpiecznym klifem. Poinformuj ich, że jesteś kapitanem i właścicielem bazy danych: rozwój będzie zgodny z opisem: przestrzegaj lub zgiń. - wallyk
Jeśli użytkownik wpisze Z, to oczywiście przechowujesz ZZ. Jeśli wejdą do ZZ, przechowujesz ZZZ i tak dalej. Wymaga to zwiększenia wszystkich kolumn o jeden znak, ale nie powinno to stanowić problemu. - Chas. Owens


Jest to z pewnością jedna z najdziwniejszych opinii, jakie kiedykolwiek słyszałem. Używanie magicznej wartości do reprezentowania "żadnych danych" zamiast NULL oznacza, że ​​każdy fragment kodu, który masz, będzie musiał postprocesować wyniki na koncie / odrzucić wartości "brak danych" / "Z".

NULL jest wyjątkowy ze względu na sposób, w jaki baza danych obsługuje go w kwerendach. Na przykład, weź te dwa proste zapytania:

select * from mytable where name = 'bob';
select * from mytable where name != 'bob';

Gdyby name jest zawsze NULL, oczywiście nie pojawi się w wynikach pierwszego zapytania. Co ważniejsze, nie pojawi się również w wynikach drugiego zapytania. NULL nie pasuje do niczego innego niż jawne wyszukiwanie NULL, jak w:

select * from mytable where name is NULL;

A co się dzieje, gdy dane mogą mieć Z jako prawidłową wartość? Powiedzmy, że przechowujesz czyjś środkowy inicjał? Czy Zachary Z Zonkas byłby skupiony na tych ludziach bez środkowego inicjału? A może twój kontrahent wymyśli kolejną magiczną wartość, aby sobie z tym poradzić?

Unikaj wartości magicznych, które wymagają implementowania funkcji bazy danych w kodzie, który jest już w stanie obsłużyć. Jest to rozwiązany i dobrze rozumiany problem, a może się tak zdarzyć, że twój kontrahent nigdy nie zgodził się z pojęciem NULL i dlatego unikał jego używania.


26
2017-07-10 00:24





Jeśli domena zezwala na brakujące wartości, to użycie wartości NULL do oznaczenia "niezdefiniowanej" jest całkowicie w porządku (po to jest dostępna). Jedynym minusem jest to, że kod zużywający dane musi zostać zapisany w celu sprawdzenia wartości NULL. Tak zawsze to robiłem.

Nigdy nie słyszałem (ani nie widziałem w praktyce) użycia "Z" do przedstawienia brakujących danych. Co się tyczy "wykonawcy wymienia to jako" standardową praktykę "wśród DBAs", czy może on dostarczyć pewnych dowodów na to twierdzenie? Jak wspomniałem @Dems, musisz również udokumentować, że "Z" nie oznacza "Z": co z MiddleInitial kolumna?

Lubić Aaron Alton i wiele innych, uważam, że wartości NULL są integralną częścią projektowania baz danych i powinny być stosowane tam, gdzie to właściwe.


22
2017-07-10 00:05



+1: Niezły link :) [Nadal mówię o zwolnieniu kontrahenta.] - MatBailie
Myślę, że kluczem jest tutaj: "Jeśli domena dopuszcza brakujące wartości ..." Wydaje mi się, że jest czas i miejsce, w którym można by wykorzystać wykorzystanie NULL, a także czas i miejsce, w którym należy ich unikać, i wymaga to trochę mądrości znać różnicę. Czasami mam wrażenie, że gdy młodszy DBE / DBA odczytuje zastrzeżenie, "wartości NULL mogą powodować nieoczekiwane wyniki w zapytaniach i obliczeniach, jeśli nie odpowiadasz za ich zachowanie", jego reakcja na kolana polega na oznaczeniu wszystkich NULL tak źle. Kiedy staje się religijną opinią, pozostaje z nim do końca swojej kariery. - Boris Nikolaevich
Zapomnienie klauzuli WHERE o DELETE lub UPDATE może spowodować uszkodzenie bazy danych => nigdy ich nie używaj. Zdobądź dane za pierwszym razem lub otwórz tabelę w edytorze i zrób to sam. - MatBailie
Z jest używane do reprezentowania strefy czasowej GMT w niektórych standardach. - Erick Robertson
@Erick, to kolejny powód, dla którego nie należy używać Z, aby oznaczać "brak wartości". - Boris Nikolaevich


Nawet jeśli w jakiś sposób uda ci się wytłumaczyć wszystkim obecnym i przyszłym programistom i administratorom bazy danych o "Z" zamiast NULL, a nawet jeśli wszystko doskonale zakodowane, to nadal będziesz mylić optymalizator, ponieważ nie będzie wiedział, że to ugotowałeś .

Używanie specjalnej wartości do reprezentowania wartości NULL (która jest już specjalną wartością reprezentującą wartość NULL) spowoduje wypaczenia danych. na przykład Tak wiele rzeczy wydarzyło się w dniu 1 stycznia 1900 roku, że wyrzuci zdolność optymalizatora do zrozumienia faktycznego zakresu dat, które naprawdę są istotne dla twojej aplikacji.

To tak, jak menedżer decydujący: "Noszenie krawata jest szkodliwe dla produktywności, więc wszyscy będziemy nosić maskę na szyje." Problem rozwiązany. "


17
2017-07-10 01:46



+1 tylko dla frazy "Używanie specjalnej wartości do reprezentowania wartości NULL (która jest już specjalną wartością reprezentującą NULL)". . . - Mike Sherrill 'Cat Recall'
Pomyślałem, że muszka jest dokładnie taka, krawat na szyi, który zastąpiono taśmą maskującą, uważaną za bardziej odpowiednią na tę okazję ... - Soren


Nigdy nie słyszałam o szerokim użyciu 'Z' jako substytut NULL.

(Nawiasem mówiąc, nie chciałbym szczególnie pracować z kontrahentem, który mówi ci w twarz, że oni i inne "zaawansowane" administracje są o wiele bardziej kompetentni i lepsi od ciebie.)

 +=================================+
 |  FavoriteLetters                |
 +=================================+
 |  Person      |  FavoriteLetter  |
 +--------------+------------------+
 |  'Anna'      |  'A'             |
 |  'Bob'       |  'B'             |
 |  'Claire'    |  'C'             |
 |  'Zaphod'    |  'Z'             |
 +---------------------------------+

W jaki sposób Twój kontrahent zinterpretuje dane z ostatniego rzędu?

Prawdopodobnie wybrałby inną "wartość magiczną" w tej tabeli, aby uniknąć kolizji z prawdziwymi danymi 'Z'? Oznacza to, że musisz pamiętać kilka wartości magicznych, a także, który z nich jest używany, gdy ... jak to jest lepsze niż posiadanie tylko jednego magicznego żetonu NULLi pamiętać o regułach logiki trójwartościowej (i pułapkach), które pasują do niej? NULL przynajmniej jest standaryzowany, w przeciwieństwie do twojego kontrahenta 'Z'.

Nie lubię szczególnie NULL albo, ale bezmyślnie zastępując ją rzeczywistą wartością (albo, co gorsza, z kilkoma rzeczywistymi wartościami) wszędzie jest prawie na pewno gorszy niż NULL.

Pozwólcie, że powtórzę powyższy komentarz tutaj dla lepszej widoczności: Jeśli chcecie przeczytać coś poważnego i dobrze ugruntowanego przez ludzi, którzy są przeciw NULL, Polecam ten krótki artykuł "Jak radzić sobie z brakującymi informacjami bez korzystania z NULL" (linki do pliku PDF z Trzecia strona główna Manifestu).


9
2017-07-10 09:16





Nic w zasadzie nie wymaga wartości null dla poprawnego projektu bazy danych. W rzeczywistości istnieje wiele baz danych zaprojektowanych bez użycia wartości NULL i jest mnóstwo bardzo dobrych projektantów baz danych i całych zespołów programistycznych, którzy projektują bazy danych bez użycia zer. Ogólnie rzecz biorąc dobrze jest zachować ostrożność w dodawaniu wartości null do bazy danych, ponieważ nieuchronnie prowadzą one później do nieprawidłowych lub niejednoznacznych wyników.

Nie słyszałem o używaniu Z nazywanej "standardową praktyką" jako wartością zastępczą zamiast wartości null, ale oczekuję, że twój kontrahent odwołuje się do koncepcji wartości wskaźników ogólnie, które są czasem używane w projektowaniu bazy danych. Jednak znacznie powszechniejszym i bardziej elastycznym sposobem na uniknięcie pustych danych bez używania "fałszywych" danych jest po prostu ich zaprojektowanie. Dekomponuj tabelę tak, aby każdy typ faktów był zapisywany w tabeli, która nie ma "dodatkowych", nieokreślonych atrybutów.


4
2017-07-10 07:24



Myślę, że wykonawca dosłownie oznacza użycie "Z" jako "nie wiem". - wallyk
Niestety, @wallyk jest zasadniczo poprawny: nie jest to dyskusja akademicka lub teoretyczna; ponieważ sam jestem programistą, przeszedłem przez kod i zapisane procedury. Wykonawca używa literalnego znaku "Z" dla brakujących / nie wprowadzonych wartości. (Wartości, które w rzeczywistości są "nieznane, ale udzielono odpowiedzi" nigdy nie są NULL nawet w aktualnym projekcie bazy danych, oba używają pustych łańcuchów dla pól tekstowych lub znaku "U" dla rozwijanych list, aby wskazać, że użytkownik odpowiedział na pytanie a odpowiedź brzmiała: "Nie wiem".) - Boris Nikolaevich
@dportas - Rozumiem, że poprawny projekt bazy danych nie wymaga użycia zer, ale ponieważ jestem w "Jest czas i miejsce na użycie NULL, jeśli wiesz jak to zrobić poprawnie", głównym celem chodziło o to, aby zrozumieć, czy użycie "Z" w dobrym projekcie bazy danych przez kogoś z obozu "NoNULL" było standardowe, powszechne lub promowane przez kogokolwiek. - Boris Nikolaevich


W odpowiedzi na komentarze wykonawców

  • Pusty ciąg <> NULL
  • Pusty ciąg wymaga 2 bajtów pamięci + odczyt przesunięcia
  • NULL używa pustej bitmapy = szybciej
  • TOŻSAMOŚĆ nie zawsze zaczyna się od 1 (dlaczego marnujesz połowę swojego zasięgu?)

Cała koncepcja jest wadliwa, jak na większość innych odpowiedzi tutaj


3
2017-07-12 09:09



Mimo że; O ile pamiętam, pusty ciąg jest NULL w Oracle. - MatBailie


Chociaż nigdy nie widziałem "Z" jako magicznej wartości reprezentującej wartość null, widziałem "X" reprezentujący pole, które nie zostało wypełnione. Powiedziałem, że widziałem to tylko w jednym miejscu, a mój interfejs nie była to baza danych, ale raczej plik XML ... więc nie byłbym gotowy użyć tego argumentu za bycie powszechną praktyką.

Zwróć uwagę, że musimy radzić sobie z 'X' specjalnie i, jak wspomnieli Dems, musimy to udokumentować, a ludzie byli przez to zdezorientowani. W naszej obronie jest to zmuszone przez zewnętrznego dostawcę, a nie coś, co sami przygotowaliśmy!


1
2017-07-10 01:10



Byłoby to bardzo mylące dla baz danych, które przechowują zaznaczone pola wyboru zaznaczone przy pomocy pola "X", niezaznaczone "(spacja). Mam nadzieję, że antymateria i materia nie zostaną zmiksowane do tej samej bazy danych ... - wallyk
Myślę, że to nie zyskało żadnych głosów, ponieważ nie jest bezpośrednio związane z pierwotnym pytaniem o projekt bazy danych, ale przynajmniej muszę powiedzieć, że nawet ta "styczna" odpowiedź służy jedynie podkreśleniu absurdalności podejścia kontrahenta. (Poza tym myślę, że "Brak głosów" należy zastąpić tutaj "Z"). - Boris Nikolaevich
Jedyna odpowiedź na to pytanie. - Pindatjuh