Базы данных, плохая практика использовать ноль как троичный вариант? - PullRequest
1 голос
/ 01 марта 2011

Я никогда раньше не использовал null, я склонен избегать его использования и наличия его в моих данных. Однако я недавно разработал эту таблицу (упрощенно):

tblPeopleWhoNeedToCastVotes
User |  hasVotedYes

В этом случае hasVotedYes может иметь значение null, true или false. Нуль означает, что они еще не проголосовали (полезная информация).

Это плохая практика или нормально?

Ответы [ 6 ]

3 голосов
/ 01 марта 2011

Это действительно то, для чего предназначен NULL - там, где данные недоступны. От Википедия :

Ноль - это специальный маркер, используемый в языке структурированных запросов (SQL) для указания того, что значение данных не существует в базе данных.

Я бы не рекомендовал использовать его в качестве общего "третьего варианта", я бы пошел с tinyint и сопоставил бы его с Enum в коде. Однако, для Да / Нет и Неизвестно, я бы сказал, что NULL - это, вероятно, лучший способ, поскольку чтение 0/1/2 в базе данных будет менее ясным.

2 голосов
/ 01 марта 2011

Я бы предпочел значение DEFAULT вместо NULL.Таким образом, в базе данных, такой как MySQL, я создам столбец

hasVotedYes TINYINT(1) DEFAULT 0

, когда пользователь проголосует «против», я изменится на 1, если пользователь проголосует «за», я отмечу его как 2. Однако NULLпо умолчанию НЕ плохая практика, пока вы не обработаете NULL-объект в коде приложения.


Подумав немного больше, я думаю, значения по умолчанию - еще лучшая идея.Например, вы хотите отфильтровать пользователей, которые проголосовали за, проголосовали против или не проголосовали - вы создадите подготовленный оператор, например,

 ... where hasVotedYes = ?;

В то время как в случае значения по умолчанию NULL вы будете писать два типазапросов.

... where hasVotedYes = ?

Это работает для проголосовавших за или против дела.

.... where hasVotedYes is NULL;

Это для не проголосовавших дела.

1 голос
/ 01 марта 2011

Я использую NULL для НЕИЗВЕСТНО, но вы также должны принять во внимание логику трех значений, если вы собираетесь выполнять много операций поиска в данных, чтобы убедиться, что вы не допустили ошибку, посмотрите на это изображение: three value logic

1 голос
/ 01 марта 2011

Нуль был построен для этого использования.Это (должно) означает: не уверен, не знаю.

Единственный недостаток - когда вы хотите знать, скажем, количество людей, которые не голосовали. Да: возможно, вам придется преобразовать ноль вчто-то или результат не будет правильным.

 select * from tblPeople as t where t.hasVotedYes <> 'Y'; -- Don't counts nulls

 select * from tblPeople as t where nvl(t.hasVotedYes, 'N') <> 'Y'; -- counts nulls.
1 голос
/ 01 марта 2011

Я бы выбрал

tblPeopleWhoNeedToCastVote
User | Voted

Где голоса обнуляются: 1 = Да, 0 = Нет, Нуль = не проголосовали.

В противном случае (если не используется ноль) вам нужнознать:

A: Голосовал ли человек

B: За что он голосовал.

Если не использовать NULL B, по умолчанию будет 0. Это может раздражать, когдажелая создать запрос всех людей, проголосовавших за (1) или нет (0), вы должны проверить, проголосовал ли человек.

При использовании NULL вы можете просто запросить 1 или 0.

0 голосов
/ 01 марта 2011

Нуль используется для всех видов вещей, но обычно это приводит к противоречиям и неверным результатам.

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

Я действительно не понимаю, что вы надеетесь получить, используя ноль, чтобы представить случай, когда человек не голосовал. Почему бы вам просто не сохранить информацию, пока они не проголосуют . Таким образом, отсутствие строки ясно указывает на то, что человек еще не проголосовал.

...