Załóżmy, że masz aplikację o polu boolowskim w User
tabeli o nazwie Inactive
.
Czy jest coś z natury złego w przechowywaniu fałszu jako wartości zerowej? Jeśli tak, czy możesz wyjaśnić, co powinno być wadą? Rozmawiałem o tym z kimś kilka miesięcy temu i oboje zgodziliśmy się, że nie powinno to mieć znaczenia, o ile konsekwentnie robisz to w całej aplikacji / bazie danych. Ostatnio ktoś, kogo znam, stanowczo podkreślił, że jest „prawdziwy” true
lub false
powinien zostać użyty, ale tak naprawdę nie wyjaśnił dlaczego.
database-design
null
Ominus
źródło
źródło
Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database
jest to przyjęta mądrość i nie powinieneś redefiniować znaczenia Null w swojej aplikacji. Będzie to mylące dla wszystkich osób pracujących z twoim kodem.SELECT * FROM foo WHERE bar = FALSE
nie daje oczekiwanych rezultatów.Odpowiedzi:
Tak.
NULL to nie to samo co Fałsz.
Z definicji porównania (i logika), które obejmują NULL, powinny zwracać wartości NULL (nie False). Jednak implementacje SQL mogą się różnić.
True and NULL
ma wartość NULL (nie False).True and NULL or False
ma wartość NULL (nie False).http://en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29
http://technet.microsoft.com/en-us/library/cc966426.aspx
źródło
null
ma znaczenia dla logiki (jak ma to miejsce w przypadkuwhatever OR TRUE
lubwhatever AND FALSE
, gdy żadna wartość niewhatever
może zmienić warunku), wówczas wyrażenie zwraca wartość. To nie jest optymalizacja; tak działa logika trójwartościowa . Każdy DBMS, który nalega na zwrotUNKNOWN
/NULL
dla tych wyrażeń, jest zasadniczo uszkodzony.Zezwalając na wartości null w polu logicznym, zamieniasz zamierzoną reprezentację binarną (prawda / fałsz) w reprezentację trójstanową (prawda, fałsz, null), w której twoje wpisy „null” są nieokreślone. Wartość „null” nie jest odpowiednio „prawdziwa” ani „fałszywa”. Jaki powód musiałbyś zwiększyć swoją reprezentację, aby była niedokładna?
Nawet jeśli zdecydujesz się na taki wzór i robisz to konsekwentnie przez całą aplikację, nie jest to w porządku. Skończysz w sytuacji, w której świeże oczy nie są jasne, dlaczego ten wzór jest na miejscu, lub, co bardziej prawdopodobne, skończysz w sytuacji, w której ten wzór zostanie przypadkowo złamany.
źródło
Co powiedzieli inni. 3 możliwe wartości nie są wartością logiczną.
Ale możesz mieć uzasadnioną potrzebę 3 wartości. Takich jak (prawda, fałsz, nieznane). Nawet jeśli tak jest, jeśli jesteś w ultra-normalizacji, w ogóle nie zezwalasz na wartości zerowe. Zamiast tego będziesz przechowywać prawdziwą wartość logiczną w innej tabeli z relacją 1 do 1. Wartość null może zostać wygenerowana w zapytaniu przez „nieudane” połączenie zewnętrzne, a nie przez fizycznie zapisaną wartość null.
źródło
false
), to mają swoje miejsce. Gdyby nie, nie istnieliby. Alternatywą, jak wspomniano, jest zasadniczo posiadanie całej innej tabeli z tylko kluczem podstawowym wiersza i pojedynczą wartością logiczną (lub int, lub varchar lub co masz). Dla każdego pola, które w innym przypadku byłoby zerowane. Chociaż względnie czysty, jest zbyt zawiły dla większości celów.Czy
bool?
to typ boolowski? Nie, to jest typuNullable<T>
gdzieT
jest logiczna. Zerowalne boolean może mieć 3 wartości: true, false i null. Aby użyćbool
lubbool?
zależy od wymagań. Może istnieć uzasadniony powód, dla którego może być konieczne użycie wartości null, ale typu, który pachnie jak binarny, ale nie znasz odpowiedzi. W powyższym przykładzieUser.IsActive
wydaje się jasne. Użytkownik jest aktywny czy nie. Jako system może chcieć wiedzieć, czy użytkownik jest aktywny, czy nie. Nie powinno być „może”. Ale pomyśl o czymś takim jak flaga funkcji. Czy funkcja jest włączona? Odpowiedzi mogą być tak, nie lub niepewne. Możesz mieć regułę biznesową, która przeliteruje, że przycisk wyświetla się tylko wtedy, gdy flaga jest ustawiona na true. Można argumentować, że bool jest domyślnie fałszywy, więc po co tworzyć zerowalne bool? Odwróć wymaganie: czy ustawisz wszystkie wartości w źródle danych na true?źródło