Nasza firma współpracuje z inną firmą programistyczną dla wspólnego projektu i powiedziano nam, że jeśli konkretna wartość nie zostanie wyświetlona, powinniśmy przekazać wartość -5000 (ich arbitralna wartość wartownika); powodem jest to, że żadna kolumna liczbowa w ich bazie danych Oracle nie obsługuje wartości zerowych, na zalecenie ich (obecnie byłego) dewelopera Oracle. Ta firma pisze także znaczną większość swojego kodu w VB6 (powoli przechodząc do VB.NET, co jest kolejnym tematem na kolejny dzień ...). Czy z czystej ciekawości istnieje jakiś uzasadniony powód tego zalecenia? Nie mogę myśleć o żadnej stronie.
--- edytować
Dziękuję za opinię wszystkim. Zadałem to samo pytanie na CodeProject.com ( link ) i otrzymałem bardzo podobne opinie. Wydaje się, że jedyny raz, kiedy można zacząć uzasadniać tę praktykę, jest związany z kluczami obcymi i mogę stwierdzić, że nie używają oni żadnych kluczy obcych w systemie. Deweloper, który dokonał tego ustalenia (kiedyś pracowałem w tej firmie), ma znacznie większe doświadczenie niż ja, więc chciałem się upewnić, że nie ma żadnego uzasadnionego powodu, zanim nastąpi szyderstwo.
źródło
Odpowiedzi:
Realnie wymaganie jest szalone. Jednak, podobnie jak wszystkie wielkie szalone pomysły, opiera się prawdopodobnie na samorodku potencjalnej racjonalności, dalekim od kontekstu przez ludzi, którzy nie rozumieją uzasadnienia.
Rozsądne może być zaprojektowanie schematu bazy danych w taki sposób, aby żadne
NULL
wartości nie były dozwolone. Jeśli to zrobisz, zobowiązujesz się do poziomu normalizacji, w którym każdy niepotrzebny element jest dzielony na osobną tabelę z odpowiednim odwołaniem klucza obcego do rodzica. Nie jest to często wykonywane w praktyce, ale w przypadkach, w których ma to sens, mogą przynieść korzyści.Jeśli zamierzasz zaprojektować schemat bazy danych w taki sposób, że żadne
NULL
wartości nie są dozwolone, nie ma sensu pozwolić, aby nie mówiąc już o magicznych wartościach wskazujących, że coś jest nieznane. To wprowadza wszystkie problemy związane z dopuszczaniemNULL
wartości oraz dodaje dodatkowy kod, aby sprawdzić magiczne wartości, które muszą się powtarzać w każdym miejscu. Opracowanie interfejsu API, który wymaga przekazywania magicznych wartości bez względu na projekt bazy danych, nie ma sensu - jeśli zamierzasz kulić swój kod za pomocą sprawdzania magicznych wartości, naprawdę nie powinieneś pozwolić, aby szaleństwo rozprzestrzeniło się na inne systemy .źródło
COALESCE()
- staje się to jeszcze bardziej skomplikowane.Nie ma żadnego uzasadnionego powodu, aby użyć magicznej wartości zamiast NULL. Może to być proces myślowy kogoś, kto tworzy ten bałagan. Piszą coś takiego:
Gdy nie zwróci to oczekiwanych wyników, zdają sobie sprawę, że nie zawiera wartości NULL i będą musieli napisać:
Nie chcą pisać ani zapomnieć w przyszłości, aby to napisać, więc wymyślili rozwiązanie tworzenia wszystkich NULLS -5000. Magicznie ich oryginalne zapytanie obsługuje wartości NULL bez żadnych zmian. Nie zdają sobie sprawy, że teraz ktoś, kto chce wykluczyć te wartości, musi napisać:
Lub jeśli chcieli te wartości i szukają wyższego zakresu:
Mogą również nie zdawać sobie sprawy, że następujące elementy nie będą już mieć znaczenia:
Zamiast tego osoba musi pamiętać magiczną wartość. Z każdym użytym typem danych muszą pamiętać więcej magicznych wartości, np. 1/1 // 1900, „Z”, -5000. Ponadto, gdy wartość magiczna znajduje się w danych, muszą także pamiętać alternatywne wartości magiczne.
Tak więc dla jednego konkretnego przypadku upraszcza kod kosztem innych przypadków, nie wspominając o miejscu na dysku, rozmiarze indeksu, analizie zapytań, spójności itp.
źródło
To totalne szaleństwo i nie ma na to żadnego uzasadnienia.
NULL
został utworzony, aby reprezentować brak wartości, a użycie rzeczywistej wartości, takiej jak -5000, jest dziwactwem.Zwykle nie napisałbym odpowiedzi tak krótko, ale pytanie zasługuje na bycie jednym z najbardziej widocznych na dba.se, a im więcej odpowiedzi, tym lepiej.
źródło
Pomyślałem o tym przez chwilę, próbując być pozytywnym i uzasadnić potrzebę użycia dowolnej wartości zamiast wartości zerowej i wydaje mi się (przynajmniej dla mnie), że nie ma uzasadnionego powodu, z wyjątkiem być może w zamkniętym zestawie danych do eksploracji danych w celu poprawy i uproszczenia wydajności i zapytań, a następnie tylko w przypadkach, w których liczby nie są wartościami, które mogą wypaczać dane. Nawet to należałoby rozważyć ostrożnie. We wszystkich rzeczywistych sytuacjach nadanie wartości zerowej nie jest dobrą praktyką. To zmienia definicję kolumny NOT NULL od twojego przyjaciela na wroga, ponieważ tak naprawdę nie jest to prawdą.
Zupełnie inaczej jest powiedzieć, że nasza aplikacja nie powinna przyjmować wartości NULL dla niektórych (lub nawet wszystkich) kolumn. Jest to rozsądna i dobra praktyka oraz istnieją dobrze udokumentowane korzyści z niedozwolenia wartości zerowych (na przykład klucze i indeksy oraz obliczenia statystyczne). Jednak przypisanie wartości „usiądź w miejscu” wartości zerowej wcale nie jest takie samo. Jest to pręt dla twoich własnych pleców, ponieważ musisz najpierw wybrać wartość, która nigdy nie będzie nigdy używana, odfiltruj tę wartość, tak jak w przypadku wartości zerowej, i pamiętaj, aby nie używać jej w obliczeniach i podsumowaniach oraz usuwać ją z zewnętrznych źródeł danych . Jest to co najmniej tak samo złe, jak użycie wartości null do przedstawienia rzeczywistej wartości, o czym mówisz sobie, że unikasz, ale tak nie jest.
Większość problemów, które powodują null, po zrozumieniu, można rozwiązać (lepsza normalizacja, indeksy oparte na funkcjach lub bitmapy lub zwykłe GDZIE x NIE JEST NULL). Czy uważasz, że w jakimś dużym Telco lub w Amazon na comiesięcznym spotkaniu dotyczącym wydajności niektóre DBA przedstawia ten wspaniały plan, aby nieco przyspieszyć zapytania dotyczące ich ogromnych zestawów danych, zastępując wartość null dowolną wartością, np. -5000 lub czymkolwiek - Jestem otwarty na wartość ... ”. A może myślisz, że spędzają czas na lepszym projektowaniu aplikacji, aby odfiltrować niepożądane wartości zerowe i optymalizować zapytania w oparciu o rzeczywiste dane, które otrzymują ? OK, dobrze, może comiesięczne spotkanie jest trochę optymistyczne, ale za każdym razem, gdy się one zdarzają, zapewniam cię, że „Zastąpienie wartości zerowej wartością -5000 (lub cokolwiek innego) dla lepszego interfejsu API” nie jest przedmiotem programu.
Dla mnie dobrze jest powiedzieć, że nie zaakceptuję brakujących danych (musisz mieć wiek, cenę, kod regionu lub cokolwiek innego), a czasem nawet dobrze jest powiedzieć, że w tej kolumnie jest wartość domyślna, która zostanie wprowadzona, jeśli nie stawiasz czegoś innego. Nie jest dobrze, aby odłożyć wartość na zero. Pomyśl o polach drugiego imienia jako przykład. Czasami nie będą one istnieć, ponieważ rodzice są zbyt leniwi, aby wypełnić wszystkie pola. Czy dodajemy do naszych danych „brak”, „brak” lub „nieznane”, aby usprawnić nasze wyszukiwanie? Nie, ponieważ mogą istnieć dziwni ludzie, którzy zmieniają swoje nazwy na te wartości, więc kiedy drukujemy dane, nie wiemy, czy musimy je uwzględnić, czy nie. Jest to prosty, ale dalekosiężny przykład. Wiemy o NULL i mamy przewidywalne wbudowane funkcje, aby sobie z tym poradzić. Nie możesz tego lepiej kodować.
Jeśli żadna odpowiedź (lub NULL) nie jest prawidłową odpowiedzią na twoje żądanie wejściowe, nie zezwalaj na to w aplikacji lub bazie danych, jeśli jest to dobra odpowiedź, musisz zezwolić na nią zarówno w aplikacji, jak i bazie danych i poradzić sobie z to jako poprawna odpowiedź. Jeśli jest to część zestawu prawidłowych odpowiedzi, twoja baza danych musi być zaprojektowana do jej przechowywania. W końcu nie mówisz hej, pola liczbowe są tak nudne, że pozwalają przechowywać liczby w kroplach i używać zdjęć dzikich zwierząt do reprezentowania każdej liczby, ponieważ to orzechy (fajne, ale orzechy). Nie decydujemy również, że nie podoba nam się litera B i jak jakiś okrutny koszmar z Ulicy Sezamkowej zamień ją na # w naszych danych. Jeśli B nie jest odpowiedzią, chcemy, abyśmy odpowiedzieli użytkownikowi „Hej, nie możesz tu wstawić B”. Po co więc traktować null inaczej?
Unikaj więc zer, których nie chcesz na poziomie aplikacji, i zajmuj się nimi w bazie danych, gdzie akceptujesz je w przeciwnym razie, tak jak żyrafa + żyrafa = hipopotam, twoje bezsensowne sprowadzanie danych sprawi ci kłopotów.
źródło