Чи слід зберігати False як Null в булевому полі бази даних?


20

Скажімо, у вас є додаток, який має булеве поле у ​​своїй Userтаблиці під назвою Inactive.

Чи є щось по суті не так у тому, щоб просто зберігати false як null? Якщо так, чи можете ви пояснити, якою має бути нижня сторона? Я обговорював це з кимось кілька місяців тому, і ми обоє погодилися, що це не має значення, доки ви це робите послідовно в додатку / базі даних. Нещодавно хтось, кого я знаю, наголошував на тому, що це "правда" trueабо його falseслід використовувати, але вони насправді не давали пояснення, чому це відбувається.


25
Вікіпедія говорить, що Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database це загальноприйнята мудрість, і ви не повинні переосмислювати, що означає Null у вашій заявці. Це буде заплутати всіх, хто працює з вашим кодом.
PersonalNexus

10
Чому ви навіть хотіли це зробити? Чому б просто не використати бітове поле, яке не зводиться до нуля, і встановити за замовчуванням значення false, якщо це поведінка, яку ви хочете, замість плутати проблему з тридержавним полем?
JohnFx

5
Приклад у реальному світі, чому це дуже погана ідея: SELECT * FROM foo WHERE bar = FALSEне дає результатів, яких ви очікуєте.
Blrfl

2
Розглянемо використання стовпця int зі значенням за замовчуванням 0, а не булевим. Таким чином, якщо виникають нові умови (наприклад, стан "очікування"), вам не потрібно змінювати структуру бази даних.
ГрандмайстерB

4
Але якщо ви зберігаєте false як null, як ви збираєтесь зберігати FILE_NOT_FOUND ?! ( thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx )
Ед Джеймс

Відповіді:


50

Чи є щось по суті не так у тому, щоб просто зберігати false як null?

Так.

Якщо так, чи можете ви пояснити, якою має бути нижня сторона?

NULL - це не те, що False.

За визначенням, порівняння (та логіка), які включають NULL, повинні повертати значення NULL (не False). Однак реалізація SQL може відрізнятися.

True and NULL є NULL (не помилково).

True and NULL or False є NULL (не помилково).

http://en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29

http://technet.microsoft.com/en-us/library/cc966426.aspx


3
Пояснення суцінки щодо того, чому NULL - це значення, що представляє відсутність значення.
maple_shaft

2
Перший день моєї першої роботи з розробки включав налагодження та виправлення помилки, як у цьому питанні / відповіді, нагадування +1
цундоку

1
Зауважте, що сама стаття, з якою ви посилаєтесь, говорить про те, що якщо nullзначення не має відношення до логіки (як це має місце whatever OR TRUEабо whatever AND FALSE, коли жодне значення не whateverможе змінити умову), то вираз повертає значення. Це не оптимізація; так працює 3-цінна логіка . Будь-яка СУБД, яка наполягає на поверненні UNKNOWN/ NULLдля цих виразів, принципово порушена.
cHao

1
@ S.Lott, але не зберігає null замість false, економте простір ??
azerafati

2
@Bludream: Для булевих змінних поле фактично може займати більше місця, залежно від СУБД. (Хоча це майже незначна кількість у майже всіх випадках.) Булева може бути представлена ​​в одному біті ... але нульовий булевий має три можливі значення (true, false і null), і тому потрібно більше одного біта.
cHao

15

Дозволяючи нулі в булевому полі, ви перетворюєте призначене бінарне подання (справжнє / хибне) в тридержавне представлення (істинне, помилкове, нулеве), де ваші "нульові" записи невизначені. Значення "null" не є ні належним чином "true", ні "false". З якої причини ви мали б збільшити своє уявлення як неточне?

Навіть якщо ви вирішите такий шаблон, як цей, і зробите це послідовно протягом усієї програми, це не робить це нормальним. Ви опинитесь в ситуації, коли свіжим очам не зрозуміло, чому такий візерунок стоїть на місці, або, швидше за все, ви опинитеся в ситуації, коли цей шаблон ненавмисно порушений.


5

Що сказали інші. 3 можливі значення не булеві.

Але у вас може бути законна потреба у 3 значеннях. Такі як (справжнє, хибне, невідоме). Навіть якщо це так, якщо ви перебуваєте ультра-нормалізації, ви взагалі не дозволите жодних нульових значень. Натомість ви зберігаєте справжній булевий файл в іншій таблиці зі співвідношенням 1 до 1. Нульове значення може бути створене в запиті за допомогою "невдалого" зовнішнього з'єднання, а не фізично збереженого нульового значення.


за межами сфери мого булевого запитання, чому справжня невідома невідома була б поганою, якщо ви використовували null для цього? Поза моїм питанням, чи варто взагалі уникати нулів? Чому?
Омінус

3
@Ominus: Нулі, як правило, слід уникати, якщо ти пурист. Якщо вони використовуються так, як вони мали бути використані (як "тут немає значення", а не як підробка false), то вони мають своє місце. Якби їх не було, вони не існували б. Як згадувалося, як альтернатива, як правило, є ціла інша таблиця з первинним ключем вашого рядка та одним булевим (або int, або varchar, або що у вас є). Для кожного поля, яке ви в іншому випадку зробите нульовим. Хоча відносно чистий, для більшості цілей він занадто перекручений.
cHao

-3

Є чи bool?булева типу? Ні . Це типу , Nullable<T>де Tбулева. Nullable булева може мати 3 значення: true, false та null. Використовувати boolабо bool?залежить від вашої вимоги. Може бути законна причина, коли вам може знадобитися використовувати null, але тип, який пахне бінарним, але ви не знаєте відповіді. У наведеному вище прикладіUser.IsActiveздається чітким вирізом. Користувач активний чи ні. Як система, можливо, захоче знати, активний чи ні користувач. Не може бути "можливо". Але подумайте про щось на зразок прапора. Чи включена функція? Відповіді можуть бути так, ні чи не впевнені. Можливо, у вас є ділове правило, яке чітко показує кнопку, лише якщо прапор встановлено на істинне. Можна стверджувати, що bool за замовчуванням помилковий, тож навіщо створювати нульовий bool? Зворотна вимога: чи збираєтесь ви встановити всі значення в джерелі даних як істинні?


2
цю публікацію досить важко читати (стіна тексту). Ви б не хотіли відредагувати його на кращу форму?
гнат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.