Должен ли я хранить False как Null в логическом поле базы данных?

20

Допустим, у вас есть приложение с логическим полем в Userтаблице Inactive.

Есть ли что-то по сути неправильно просто хранить false как ноль? Если да, то можете ли вы объяснить, какой должна быть обратная сторона? Я обсуждал это с кем-то несколько месяцев назад, и мы оба согласились, что это не должно иметь значения, если вы делаете это последовательно в приложении / базе данных. В последнее время кто-то из моих знакомых подчеркивал, что это «правда» trueили falseследует использовать, но они не дали объяснения, почему.

Ominus
источник
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, а не с логическим значением. Таким образом, если возникают новые условия (например, состояние ожидания), вам не нужно изменять структуру базы данных.
GrandmasterB
4
Но если вы храните false как ноль, как вы собираетесь хранить FILE_NOT_FOUND ?! ( thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx )
Эд Джеймс

Ответы:

50

Есть ли что-то по сути неправильно просто хранить false как ноль?

Да.

Если да, то можете ли вы объяснить, какой должна быть обратная сторона?

NULL - это не то же самое, что False.

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

True and NULL НЕДЕЙСТВИТЕЛЕН (не Ложен).

True and NULL or False НЕДЕЙСТВИТЕЛЕН (не Ложен).

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
tsundoku
1
Обратите внимание, что в самой статье, на которую вы ссылаетесь, говорится, что если nullона не имеет отношения к логике (как в случае whatever OR TRUEили whatever AND FALSE, где никакое значение не whateverможет изменить условие), то выражение возвращает значение. Это не оптимизация; это то, как работает 3-значная логика . Любая СУБД, которая настаивает на возврате UNKNOWN/ NULLдля этих выражений, в корне сломана.
cHao
1
@ S.Lott, но не хранит нулевое значение вместо ложного, сохраняет немного места ??
Азерафати
2
@Bludream: Для логических значений поле, которое может быть пустым, может занимать больше места, в зависимости от СУБД. (Однако это незначительная величина почти во всех случаях.) Логическое значение может быть представлено одним битом ... но логическое значение, допускающее значение NULL, имеет три возможных значения (true, false и null) и, следовательно, требует более одного бита.
Цао
15

Допуская нулевые значения в логическом поле, вы превращаете намеченное двоичное представление (true / false) в представление с тремя состояниями (true, false, null), где ваши «нулевые» записи являются неопределенными. Значение 'null' не является ни соответствующим образом 'true', ни 'false'. По какой причине вы должны увеличить свое представление, чтобы быть неточным?

Даже если вы выберете такой шаблон и будете делать это последовательно во всем приложении, это не поможет. Вы окажетесь в ситуации, когда свежим глазам непонятно, почему этот паттерн на месте, или, что более вероятно, вы окажетесь в ситуации, когда этот паттерн непреднамеренно нарушен.

Джейкоб Маристани
источник
5

Что сказали другие. 3 возможных значения не булево.

Но у вас может быть законная потребность в 3 значениях. Такие как (правда, ложь, неизвестно). Даже если это так, если вы занимаетесь ультранормализацией, вы вообще не допустите нулевые значения. Вместо этого вы сохраните истинное логическое значение в другой таблице с отношением 1: 1. Нулевое значение может быть получено в запросе с помощью «неудачного» внешнего соединения, а не с помощью физически сохраненного нулевого значения.

Лорд тидус
источник
за пределами моего логического вопроса, почему истинное ложное неизвестное будет плохим, если вы используете ноль для этого? Помимо моего вопроса вообще следует избегать нулей? Почему?
Ominus
3
@ Ominus: Нулевых, как правило, следует избегать, если вы пурист. Если использовать их так, как они должны были быть использованы (так как «здесь нет никакой ценности», а не как «фальшивка-подделка» false), то у них есть свое место. Если бы они этого не сделали, их бы не было. Альтернатива, как уже упоминалось, в основном состоит из совершенно другой таблицы, содержащей только первичный ключ вашей строки и один логический (или int, или varchar, или что у вас). Для каждого поля, которое в противном случае вы могли бы сделать обнуляемым. Хотя он относительно чистый, он слишком сложен для большинства целей.
Чао
-3

Это bool?логический тип? Нет, это тип, Nullable<T>где Tлогическое. Обнуляемое логическое значение может иметь 3 значения: true, false и null. Для использованияbool или bool?зависит от вашего требования. Может быть законная причина, по которой вам может понадобиться использовать null, но тип, который пахнет как двоичный, но вы не знаете ответ. В приведенном выше примереUser.IsActiveкажется четким. Пользователь активен или нет. Как система, она может захотеть узнать, активен ли пользователь или нет. Там не должно быть «возможно». Но подумайте о чем-то похожем на флаг функции. Функция включена? Ответы могут быть да, нет или не уверен. У вас может быть бизнес-правило, которое излагает только показ кнопки, когда флаг установлен в значение true. Кто-то может возразить, что bool по умолчанию ложен, так зачем создавать недействительные bool? Обратное требование: собираетесь ли вы установить для всех значений в источнике данных значение true?

nullableTypes
источник
2
этот пост довольно трудно читать (стена текста). Не могли бы вы изменить его в лучшую форму?
комнат