W jaki sposób nazwisko Null powoduje problemy w wielu bazach danych?

71

Przeczytałem artykuł o BBC. Jednym z podanych przez nich przykładów jest to, że osoby o nazwisku „Null” mają problemy z wprowadzeniem swoich danych na niektórych stronach internetowych.

Nie podano wyjaśnienia dotyczącego napotkanego błędu.

Ale o ile wiem, ciąg „Null” i faktyczna wartość Null jest zupełnie inna (z punktu widzenia bazy danych).

Dlaczego miałoby to powodować problemy w bazie danych?

Nitish
źródło
2
Jest to dość znany artykuł na blogu o założeniach, które programiści robią na temat nazwisk, napisany przez jedną z osób cytowanych w tym artykule BBC: kalzumeus.com/2010/06/17/…
Jörg W Mittag
12
Odpowiedni xkcd
David Grinberg
4
Gdy pierwszy raz zobaczyłem tego gościa w telewizji, uznałem, że to błąd bazy danych. Potem dowiedziałem się, że to właściwie jego imię.
Nate Eldredge
3
@JarrodRoberson Jak możesz powiedzieć, że „cała przesłanka jest fałszywa”, biorąc pod uwagę opis problemów napotykanych przez „Jennifer Null” i podobną nazwę w linku opublikowanym przez PO? To prawdziwy problem, z którym zmagają się prawdziwi użytkownicy końcowi.
Steven Burnap

Odpowiedzi:

102

Nie powoduje problemów z bazą danych. Powoduje to problemy w aplikacjach napisanych przez programistów, którzy nie rozumieją baz danych. U podstaw problemu leży to, że wiele programów związanych z bazą danych wyświetla rekord NULL jako ciąg NULL. Gdy aplikacja polega na postaci ciągu rekordu NULL (prawdopodobnie również przy użyciu operacji porównania bez rozróżniania wielkości liter), wówczas taka aplikacja będzie traktować dowolny "null"ciąg znaków jako NULL. W związku z tym uznano by, że nazwa Null nie istnieje w tej aplikacji.

Rozwiązaniem jest zadeklarowanie kolumn niepustych jak NOT NULLw bazie danych i nie stosowanie operacji na łańcuchach do rekordów bazy danych. Większość języków ma doskonałe interfejsy API baz danych, które sprawiają, że interfejsy na poziomie łańcucha są zbędne. Powinny być zawsze preferowane, również dlatego, że popełniają inne błędy, takie jak wstrzyknięcie SQL.

amon
źródło
30
W takim przypadku jednak, jeśli czytasz ten artykuł, utworzenie pola nazwiska NOT NULLspowoduje cały zestaw problemów dla innych osób. „Niektóre osoby mają tylko jedno imię, a nie imię i nazwisko”.
MikeTheLiar
41
@Darkhogg wiele osób nie zgadza się ze mną w tej sprawie, ale myślę, że imiona są jak adresy e-mail - nie zawracaj sobie głowy ich weryfikacją, daj użytkownikowi jedno pole tekstowe i pozwól mu wstawić co tylko zechce. To informacja, że ​​jeśli naprawdę będę jej potrzebować, otrzymam ją od ciebie w sposób, który z pewnością będzie poprawny.
MikeTheLiar
8
@mikeTheLiar Nie znam nazwy tego, ale istnieje cała klasa błędów wynikających z tworzenia zbyt restrykcyjnych reguł dotyczących danych. Często zobaczysz kody pocztowe i numery telefonów zdefiniowane jako numeryczne w aplikacjach i bazach danych. Nie są tak naprawdę liczbami, ponieważ nie ma sensu wykonywać na nich operacji matematycznych. Więc kiedy ktoś próbuje wprowadzić kanadyjski adres, utknie.
JimmyJames
19
@JimmyJames tak, kody pocztowe przechowywane w postaci cyfr i nagle każdy, kto tu mieszka, ma kod pocztowy Base-8. „Jeśli nie robisz z tym matematyki, jest to ciąg znaków, Full Stop”.
MikeTheLiar
8
@mikeTheLiar. Problem z traktowaniem nazwisk jako pojedynczego ciągu (zwykle lepiej, zgadzam się) polega na tym, że istnieje wymóg alfabetycznego sortowania według nazwiska.
TRiG
13

Aby odpowiedzieć na konkretne pytanie, istnieje wiele kroków wzdłuż łańcucha zdarzeń między formularzem internetowym a bazą danych. Jeśli nazwisko Nullzostanie błędnie zinterpretowane jako NULLwartość, system może odrzucić całkowicie poprawną nazwę jako niepoprawną. Może się to zdarzyć w warstwie bazy danych, jak wyjaśnia amon . Nawiasem mówiąc, jeśli jest to specyficzny problem, baza danych jest prawdopodobnie otwarta na iniekcję SQL AKA atak Bobby Tables . Kolejnym krokiem w łańcuchu, który może powodować problemy, jest proces serializacji .

Ogólnie artykuł dotyczył większego problemu. Świat jest dużym bałaganem, który nie zawsze odpowiada naszym założeniom. Jest to szczególnie widoczne, gdy próbujesz internacjonalizować swoją aplikację. Na koniec dnia musimy upewnić się, że nasze aplikacje poprawnie obsługują i kodują nasze dane . Do firmy należy decyzja, ile zasobów przeznaczymy na obsługę coraz bardziej skomplikowanych przypadków skrajnych. Chociaż w pełni popieram włączenie, zrozumiem, czy firma zdecyduje, że „artysta formalnie znany jako Prince” musi użyć znaku Unicode, aby przedstawić swoje imię w naszej bazie danych.

Erik
źródło
Trudno sobie wyobrazić, że jest to spowodowane niebezpieczną interpolacją łańcucha, która może prowadzić do wstrzyknięcia SQL. Jeśli zapomnisz zacytować dane wprowadzane przez użytkownika w zapytaniu SQL (np. INSERT INTO users (first, last) VALUES($first, $last)Ocenia INSERT INTO users (first, last) VALUES(Jennifer, Null)), wszyscy, których nazwy nie są poprawnymi słowami kluczowymi SQL lub nazwami kolumn, będą po prostu zgłaszać błędy i nie będą mieć również swoich rekordów. Przyczyna musi być bardziej złożona.
Andrew Medico,
@AndrewMedico w twoim słomkowym przykładzie tak, ale istnieje wiele sposobów, aby zrobić coś źle. Nigdy nie lekceważ siły <strajku> głupoty <strajku> ignorancji. Najważniejsze jest to, że nie mamy pojęcia, jaki jest rzeczywisty problem, ponieważ nie możemy przejrzeć tego kodu
Erik
7

Cóż, zanim zostanie wprowadzony do bazy danych, jest to element DOM, następnie zmienna javascript przekazywana, sprawdzana i modyfikowana, następnie wartość JSON, następnie zmienna w dowolnej bibliotece JSON, z której korzystasz, a następnie zmienna jest przekazywana, sprawdzone i zmanipulowane w języku programowania zaplecza, następnie element jakiegoś DAO, a następnie część ciągu SQL. Następnie, aby odzyskać wartość, robisz to wszystko w odwrotnej kolejności. Jest wiele miejsc, w których programiści mogą popełniać błędy, i zwykle wiele z nich bez korzyści płynących z pisania statycznego.

Karl Bielefeldt
źródło
2

Najprawdopodobniej jest to problem programistyczny. Jeśli spojrzysz na tę odpowiedź tutaj, w jaki sposób przekazywane są wartości NULL, możesz łatwo wywołać niepożądane zachowanie, jeśli jesteś „Panem Null”.

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

Widać, że jeśli jakiś element danych zostałby przekazany jako NULL, dane byłyby interpolowane jako baza danych null w bazie danych.

„NULL”! = Baza danych Null

Niektóre przypadki użycia i powiązane zachowania ...

Powiedzmy, że nazwisko zostało zaznaczone w bazie danych jako nie puste, teraz po wstawieniu danych zostanie zinterpretowane jako NULL i wstawienie nie powiedzie się.

Innym przypadkiem jest powiedzmy, że nazwisko było zerowalne w bazie danych. Pan NULL został wstawiony i przekształcony w DBNull.Value, który nie jest tym samym co „NULL”. Po wstawce nie możemy znaleźć Pana Null, ponieważ jego nazwisko nie brzmi „NULL”, ale w rzeczywistości jest to wartość zerowa bazy danych.

Byłyby to więc 2 przypadki problemów. Jak wskazuje @Amon, same bazy danych nie mają problemów z wartościami zerowymi, chociaż należy zrozumieć, jak obsługiwane są wartości zerowe w każdej instancji RDMS, ponieważ będą istnieć różnice między różnymi dostawcami.

Jon Raynor
źródło
„Widać, że jeśli jakiś element danych zostałby przekazany jako NULL, dane byłyby interpolowane jako baza danych null w bazie danych.” - wydaje się, że powiązane pytanie SO / zaakceptowana odpowiedź nie pokazuje?
MrWhite
2

Przypisałbym ten problem niechlujnemu programowaniu i złemu projektowaniu niektórych implementacji SQL. „Null” nazwa powinna zawsze być prezentowana i interpretowana w cudzysłowie. null, wartość bazy danych, zawsze powinna być prezentowana bez cudzysłowów; ale pisząc kod ad-hoc, łatwo jest przejść do paradygmatu „cokolwiek zrobi” i zaakceptować rzeczy uważane za ciąg znaków w formie niecytowanej.

Sytuację pogarsza fakt, że inne typy danych; liczby na przykład mogą i są akceptowane w dowolnej formie, ponieważ interpretacja jest jednoznaczna.

ddyer
źródło
Z pewnością masz na myśli słabe implementacje aplikacji korzystających z SQL? Żadna poważna implementacja samego RDBMS nie byłaby na to narażona (podobnie jak żadna poważna aplikacja!)
podkreślenie_d
0

Problem polega zasadniczo na tym, że termin „null” stosuje się dwie różne koncepcje bazy danych, czasami używając kontekstu do ich rozróżnienia:

  1. Coś nie ma znanej wartości
  2. Coś wiadomo, że nie ma żadnej wartości

Chociaż kontekst może czasem wystarczyć do rozróżnienia tych pojęć, są chwile, w których tak naprawdę nie jest. Jeśli na przykład używasz rekordu do przechowywania zapytania, powinna istnieć różnica między powiedzeniem „Chcę kogoś o imieniu [cokolwiek], bez nazwiska”, a „Chcę kogoś o imieniu [ cokolwiek], ale nazwisko nie jest znane. ” Wiele silników baz danych ma tendencję do takiego czy innego znaczenia, ale nie wszystkie są takie same. Kod, który oczekuje, że silnik bazy danych będzie działał w jedną stronę, może działać nieprawidłowo, jeśli działa na innym silniku, który działa inaczej.

supercat
źródło
Jeśli wiadomo, że ciąg nie ma żadnej wartości, wówczas wartość powinna być ciągiem pustym, a nie ciągiem zerowym.
Byron Jones
0

Większość istniejących odpowiedzi koncentruje się na częściach aplikacji innych niż SQL, ale w SQL może również występować problem:

Jeśli zostanie poinstruowane, aby odfiltrować rekordy, w których nazwisko użytkownika nie jest dostępne, ktoś, kto nie rozumie dobrze SQL, może napisać filtr WHERE u.lastname != 'NULL'. Ze względu na sposób działania SQL pojawi się to, aby sprawdzić, czy u.lastname IS NOT NULL: wszystkie NULLrekordy są odfiltrowywane. Wszystkie nie- NULLrekordy pozostają.

Z wyjątkiem oczywiście rekordów, w których u.lastname == 'NULL', ale może nie być takich rekordów dostępnych podczas testowania.

Staje się to bardziej prawdopodobne, jeśli SQL jest generowany przez jakiś szkielet, w którym ten szkielet nie ujawnia łatwo dostępnego sposobu sprawdzania braku NULLnieścisłości z parametrami, a ktoś zauważy „hej, jeśli przekażę ciąg NULL, to robi dokładnie to, czego chcę! ”

hvd
źródło