Co zrobić, gdy nie możesz ustalić wartości logicznej?


38

Budujemy aplikację internetową dla firmy, której administracja istniała dotychczas tylko w arkuszach Excel. Już prawie skończyliśmy, ale ostatnio przydzielono mi zadanie zaimportowania wszystkich ich danych z tych arkuszy do naszego nowego systemu. System jest zbudowany w Javie, ale ponieważ ten import jest jednorazową sprawą, postanowiłem napisać skrypty w Pythonie i zaimportować je bezpośrednio za pomocą zapytań SQL. Nadchodzi problem. Nowe modele danych zawierają pewne nowe atrybuty, które nie są zawarte w ich istniejących danych. W większości przypadków nie stanowi to problemu, po prostu stawiam zero, gdzie nie mogę znaleźć informacji. Ale potem natrafiłem na kilka atrybutów, które są wartościami logicznymi i domyślnie nie mogą mieć wartości NULL. Najpierw próbowałem po prostu zezwolić na null dla tych pól w naszej bazie danych, ale mój starszy programista powiedział mi, żebym tego nie robił, ponieważ spowodowałoby to problemy w naszym systemie w przyszłości. A teraz nie jestem pewien, co robić. Oczywistym rozwiązaniem jest ustawienie domyślnej wartości false na każdą nieznaną wartość logiczną, ale myślę, że to też jest złe, ponieważ tak naprawdę nie wiem, czy to fałsz.

Przykład: załóżmy, że masz samochód Car, który ma parametr hasRadio. Teraz musisz zaimportować dane do tego modelu danych, ale w danych są tylko kolumny „Model” i „Kolor”, nic o tym, że ma lub nie ma radia. Co umieścisz w kolumnie „hasRadio”, jeśli z założenia nie może być pusta?

Jakie jest najlepsze podejście w tej sytuacji? Czy powinniśmy tylko poprosić firmę o ręczne uzupełnienie brakujących danych? Czy domyślnie jest to fałsz?


70
Dla mnie zezwolenie na NULL byłoby właściwym rozwiązaniem. Czy twój senior był bardziej szczegółowy niż „powodować problemy w naszym systemie w przyszłości”? Jeśli nie, poproś go o bardziej szczegółowe powody.
larsbe

48
Oczywiście powinieneś to zrobić domyślnie FileNotFound.
Ty

7
Czy można dodać pole boolowskie „isValidHasRadio” lub coś w tym stylu, czy też to wszystko psuje?
hyde

9
Prawidłowe rozwiązanie to rozważenie śmieci wejściowych i przerwanie całej transakcji, a następnie zażądanie dostosowania definicji zadania, jeśli danych tych nie można uznać za śmieci. Nie ma innej drogi tutaj.
Sarge Barszcz

17
Nawiasem mówiąc, nie jestem wielkim fanem wartości zerowych. Wolałbym używać wyliczenia z „Nieznany”, „Ma radio” i „Nie ma radia”. W ten sposób spełnisz swoje wymagania i będziesz mieć możliwość rozwoju, jeśli będziesz musiał określić rodzaj radia w przyszłości, na przykład „Radio ze zintegrowaną telewizją” lub coś w tym rodzaju.
Machado

Odpowiedzi:


129

Jest to głównie problem z analizą wymagań i nie ma to nic wspólnego z faktem, że przedmiotowe dane są „logiczne”. Jeśli musisz zainicjować tabele w bazie danych lub w innym rodzaju przechowywania danych i masz niepełne dane wejściowe dla niektórych kolumn, najpierw musisz dowiedzieć się, co według użytkowników systemu lub klienta będzie właściwą wartością domyślną dla tych kolumn i musisz to sprawdzić dla każdego atrybutu , ogólnie nie ma poprawnej odpowiedzi.

Zazwyczaj prowadzi to do jednego z następujących przypadków:

  • jest dobra wartość domyślna dla konkretnej kolumny, użytkownicy nie mają nic przeciwko, jeśli wartość jest początkowo taka sama dla wszystkich rekordów, mogą później łatwo ustawić poprawne wartości w razie potrzeby

  • istnieje reguła określania idealnej wartości domyślnej na podstawie innych informacji, dzięki czemu można umieścić tę regułę w kodzie

  • użytkownicy lub klient rozszerzą dane wejściowe i podadzą brakujące wartości (być może ręcznie), zanim zostaną zaimportowane do bazy danych

  • nie ma dobrej wartości domyślnej dla konkretnej kolumny i / lub żadnego rekordu, dane też należy zaimportować, ale użytkownicy chcą wiedzieć, dla którego z rekordów konkretna wartość jest już zainicjowana, a dla którego nie. Aby mogli później wprowadzić wartość i śledzić, dla których rekordów wartość jest już poprawnie ustawiona, a dla których nie.

Ostatni przypadek wymaga czegoś takiego jak NULL, aby reprezentować niezainicjowany lub nieznany stan, nawet dla wartości logicznej, jeśli twój senior to lubi, czy nie. Jeśli istnieje jakiś niejasny powód techniczny, który zabrania użycia wartości NULL dla określonej kolumny, musisz symulować stan „nieznany” w inny sposób, albo przez wprowadzenie dodatkowej kolumny boolowskiej (jak hasRadioIsUnknown), albo za pomocą 3 -valued wyliczenie zamiast wartości logicznej (jak HasNoRadio=0, HasRadio=1, Unknown=2). Ale po dokładnej analizie wymagań ponownie porozmawiaj ze swoim seniorem, aby upewnić się, że takie obejście jest naprawdę konieczne.


29
Należy również pamiętać, że ta sama odpowiedź dotyczy innych kolumn, w których wygodnie użyto NULL. Powinieneś sprawdzić, czy jest to poprawna wartość domyślna. Jeśli na przykład jakaś inna kolumna mówi „processingIsFinished”, a importujesz stare dane z historii zamówień klientów (myśląc o sklepie internetowym), być może będziesz musiał ustawić wartość „true” zamiast „NULL”, aby uniknąć uruchomienia niektórych procesów gdy napotkają wpisy, które nie zostały jeszcze przetworzone (zgodnie z ich interpretacją tej kolumny).
Frank Hopkins,

1
To jest problem funkcjonalny. Ponieważ modele (excels i nowy) nie pasują, proces migracji powinien zostać zweryfikowany z uwzględnieniem tych przypadków. Jedyne, co może powiedzieć, jak postępować, to / są interesariusze (klient lub ktokolwiek). Technicznie możesz to rozwiązać na wiele sposobów, ale funkcjonalnie tylko na jeden. Prawo.
Laiv

12
Podoba mi się ten podział. Mój niechęć do zerowania w tym kontekście wynika głównie z braku jasnego znaczenia. Nieznane jest jasne. Ale czy null oznacza nieznane czy nie dotyczy? Skąd ktokolwiek mógłby wiedzieć? To, że ma to dla ciebie sens, nie oznacza, że ​​wszyscy będą postrzegać to w ten sam sposób.
candied_orange

Opcja 4: Rekordy, w których brakuje określonej wartości kolumny, są w rzeczywistości bezużyteczne i powinny zostać wykluczone z importu. Opcja 5: ktoś musi poprawić wszystkie przychodzące dane przed ich zaimportowaniem. Wiele opcji, zależy tylko od potrzeb i budżetów. Importowanie starych danych jest zawsze ogromnym bałaganem.
jpmc26,

@ jpmc26: cóż, nie uwzględniłem opcji 4, ponieważ chciałem trzymać to, co OP napisał dosłownie (przypadek, w którym brakujące dane zdecydowanie nie są zawarte w danych importu, bez zapisu). Warto wspomnieć o opcji 5, ponieważ jest to kolejny sposób uniknięcia konieczności stosowania wartości NULL. Zredagowałem odpowiednio moją odpowiedź.
Doc Brown

39

To nie jest pytanie techniczne; to pytanie o reguły biznesowe. Musisz więc zapytać „biznes”.

Podejdź do właściciela produktu i / lub zainteresowanych stron i powiedz coś takiego:

Mamy niekompletne dane dla jednego z pól wymaganych we wniosku. Czy chcesz, abyśmy użyli wartości domyślnej? Czy chcesz, abyśmy dodali „nieznane” jako prawidłową wartość? A może chciałbyś, aby ktoś z twojego zespołu poprawił dane przed importem?

Pewna dyskusja prawdopodobnie nastąpi. Ale to w zasadzie to. Rozwiązanie techniczne wypłynie naturalnie z bardziej dopracowanych reguł biznesowych.


9

Ogólnym problemem jest cały podobszar programowania zwany czyszczeniem danych, który jest częścią większego podobszaru zwanego integracją danych . Unikanie tego rodzaju problemów jest prawdopodobnie dużą przyczyną migracji z arkuszy Excela i dlaczego starszy programista nie chce, aby pole stało się zerowalne. Nie sądzę, aby mówienie, że jest to jedno z większych źródeł złożoności migracji danych, jest nierozsądne.

Samo użycie NULL, gdy tylko jest to możliwe, jest bardzo niewłaściwym posunięciem, nie mówiąc już o zmianie modelu danych, aby jeszcze więcej pól było null. Program Excel ma słabe sprawdzanie integralności lub nie ma go wcale, co jest prawdopodobnie przyczyną wielu z tych problemów. Złą rzeczą jest usunięcie sprawdzania integralności w nowej bazie danych i zrzucenie do niej śmieci. To tylko utrwala problem i dodaje znaczną złożoność przyszłym integracjom, które w jakiś sposób muszą radzić sobie z bezsensownymi danymi.

Pewna różnica prawdopodobnie wynika z niedopasowania modelu danych. Radzenie sobie z tym jest w dużej mierze kwestią znajomości obu modeli danych i umiejętności mapowania starego na nowy. Tak długo, jak nowy jest w stanie uchwycić stary. (Jeśli nie, Twój zespół prawdopodobnie ma bardzo duży problem.) Może to z łatwością wymagać więcej pracy niż kopiowanie kolumn. Darkwing daje doskonały przykład tego (a także dlaczego ślepe wstawianie wartości NULL jest niewłaściwe). Opracowanie na nią, jeśli stary model miał ReceivedDatei InProgressnieco i nowy model ma StartDatei ProcessingEndTime, trzeba będzie zdecydować, czy i jak ustawić ProcessingEndTime. W zależności od tego, jak jest używany, rozsądnym (ale arbitralnym) wyborem może być ustawienie go tak samo jakStartDate (lub krótko potem, jeśli spowodowałoby to problemy).

Jednak pewna różnica prawdopodobnie wynika z danych, które „powinny” tam być, których brakuje lub są uszkodzone. (Najprawdopodobniej z powodu błędów wprowadzania danych lub źle obsłużonych wcześniejszych migracji lub błędów w systemach przetwarzania danych.) Jeśli nikt z twojego zespołu tego nie przewidywał, to (wspólnie) postanowiłeś spędzić 20% czasu projektu „ prawie skończone. (To był wymyślony numer, ale może być dalekogorzej lub lepiej. Zależy to od tego, ile danych jest niepoprawnych, jak ważne są, jak skomplikowane, jak łatwo jest zaangażować osoby odpowiedzialne za dane i inne czynniki.) Po ustaleniu, że dane powinny „ być ”, ale brakuje. Zwykle próbujesz określić zakres problemu, sprawdzając stare źródła danych. Jeśli są to dziesiątki lub setki wpisów, to prawdopodobnie są to błędy wprowadzania danych, a klienci odpowiedzialni za dane powinni je ręcznie rozwiązać (tj. Powiedzieć, jakie powinny być wartości.) Jeśli to miliony wpisów (lub znaczna część danych) , może być konieczne ponowne zastanowienie się, czy poprawnie zidentyfikowano, że „powinno tam być”. Może to wskazywać na błąd modelowania w nowym systemie.

Wyobraźmy sobie na przykład fakturę, która zawierała ilości i sumy na sztukę (ale nie cenę jednostkową), z tym wyjątkiem, że niektórych ilości w niewytłumaczalny sposób brakowało. Rozmowa z osobą, która przetwarza takie faktury, może dać jeden (lub więcej) z następujących scenariuszy: 1) „och, pusta ilość oznacza ilość 1”, 2) „och, wiem, że te przedmioty kosztują około 1000 $, więc najwyraźniej jest to zamówienie na 2 „, 3)” kiedy to się dzieje, sprawdzam cenę w tym innym systemie i dzielę i zaokrąglam ”, 4)„ Patrzę na to w innym systemie ”, 5)„ to nie są prawdziwe dane ”, 6)„ nigdy wcześniej tego nie widziałem ”.

Jak sugerowano, może to wskazywać na niektóre sposoby automatycznego rozwiązania sytuacji, ale należy uważać, aby rozwiązanie dotyczyło wszystkich przypadków. Często w grę wchodzą inne systemy, które mogą sprawdzać dane, i to dobrze. Jednak często jest to zła rzecz, ponieważ uzyskanie dostępu do tych systemów i ich integracja może być trudna do przeprowadzenia kontroli krzyżowej, a często wychodzi na jaw, że systemy kolidują ze sobą nie tylko przez brak niektórych danych. Często wymagana jest pewna ręczna interwencja, a w zależności od skali może również wymagać stworzenia oprzyrządowania i interfejsów specjalnie dla zadania czyszczenia danych. Często zdarza się, że dane są częściowo importowane, ale wiersze z brakującymi danymi są wysyłane do osobnej tabeli, gdzie można je przejrzeć.


14
Podsumowując: jeśli uważasz, że radzenie sobie ze starszym kodem jest nieprzyjemne, spróbuj radzić sobie ze starszymi danymi.
Peter Taylor

0

Zmień model danych.

Możesz znormalizować hasradio, a wtedy nie będzie już żadnych zer.

Jeśli nie możesz ustalić wartości logicznej, nie używaj wartości logicznej.

Zezwalając na wartość logiczną równą null, przestaje być wartością logiczną. Wartość logiczna może mieć 2 stany: Fałsz, Prawda.

Potrzebujesz 3 stanów: Fałsz, Prawda, Nieznany.

Czy masz opcję zmiany modelu danych?

(I inna rzecz, o której myślałem, jeśli w Pythonie lub java pobierasz dane ze swojej bazy danych. Odzyskujesz rekord, sprawdzasz pole hasradio, co się stanie, jeśli sprawdzisz, czy jest to prawda, czy fałsz, a zdarza się, że jest zerowy?)


2
Poprzez zmianę modelu danych i „normalizacji out hasRadio” Zakładam, że czegoś podobnego dodając nową tabelę CarFeaturesz polami Car_ID, Feature_ID, Has_Feature? To dobry pomysł.
jpa

2
@jpa to trochę trudna sytuacja. Musisz być bardzo jasny w tym, co robisz, ponieważ brak zapisu w naszej sytuacji oznacza nieznane. Chociaż często brak zapisu oznacza, że ​​nie ma on tej funkcji.
Pieter B

1
Źle na to patrzysz, Pieter. Nikt nie mówi, że a boolma więcej niż dwie wartości, ponieważ, jak powiedziałeś, nie ma. boolJest albo truealbo false. Jednak w przypadku PO, PO nie ma do czynienia boolbezpośrednio, ale raczej z Option<bool>/Maybe<bool>, który może mieć Some -> true/falselub None.
Andy,

@DavidPacker moim argumentem jest to, że z tego powodu jest to być może <bool> powinieneś przestać nazywać to czymkolwiek zdalnie podobnym, w przeciwnym razie możesz się pomylić. A jeśli nalegasz na użycie wartości logicznej, znajdź bezpieczny sposób, aby to zrobić.
Pieter B

4
Moim zdaniem zerowalna wartość logiczna jest całkowicie w porządku. Nigdy nie miałem problemów z wartościami zerowymi, chociaż spotkałem programistów, którzy to zrobili.
Andy,

-1

Jak zauważyli inni, masz tutaj wartość boolowską, która nie jest tak naprawdę boolowską, a problemem jest albo zmusić ją do bycia boolowskim, albo postępować inaczej.

To, co możesz zrobić, to zamiast jednego wyniku boolowskiego uzyskać dwa wyniki boolowskie. Mogą się zgodzić lub nie. Jeśli się zgadzają, masz bezpośredni wynik prawda / fałsz.

Jeśli jednak się nie zgadzają, to masz nieokreślony wynik i masz szansę, w zależności od okoliczności, w których się pojawi, podjąć decyzję, jak sobie z tym poradzić. W niektórych przypadkach nieokreślony wynik można najlepiej interpretować jako prawdziwy, podczas gdy w innych ten sam nieokreślony wynik można najlepiej interpretować jako fałszywy, zgodnie z najbezpieczniejszą opcją.

Pozwoliłoby to jednak na zgłoszenie wyniku jako nieokreślonego, więc ten dodatkowy niuans wartości nie zostałby całkowicie utracony, aż do momentu, w którym wartość można ostatecznie rozwiązać i zresetować.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.