NULL против Empty при работе с пользовательским вводом
Вопрос
Да, еще один вопрос о NULL и пустой строке.
Я согласен с идеей, что NULL означает «не установлено», а пустая строка означает «пустое значение».Вот моя проблема:Если значение по умолчанию для столбца равно NULL, как разрешить пользователю вводить это NULL.
Допустим, в системе создан новый пользователь.Есть поле имени и фамилии;фамилия обязательна, а имя нет.При создании пользователя человек увидит два текстовых поля: первое и последнее.Человек решает ввести только фамилию.Имя технически не установлено.Во время вставки я проверяю длину каждого поля, устанавливая для всех пустых полей значение NULL.
Просматривая базу данных, я вижу, что имя не установлено.Сразу приходит на ум вопрос: возможно, они никогда не видели поле имени (т. е. из-за ошибки).Но это не так;они ушли, если пусты.
Итак, мой вопрос: как вы решаете, когда поле должно быть установлено в NULL или пустую строку при получении пользовательского ввода?Как узнать, что пользователь хочет, чтобы поле не устанавливалось без обнаружения фокуса, или если он удалил значение... или... или...?
Связанный вопрос: Должен ли я использовать NULL или пустую строку для обозначения отсутствия данных в столбце таблицы?
Решение
Я почти никогда не использую NULL при обращении к реальным данным.При использовании для внешних ключей я бы сказал, что NULL действителен, но он почти никогда не действителен для данных, вводимых пользователем.Единственное исключение, которое, вероятно, будет возникать довольно часто, — это несуществующие даты, например база данных сотрудников с полем «termination_date».В этом случае все текущие сотрудники должны иметь значение NULL в этом поле.Что касается фактического ввода нулевого значения, то для значений, которые действительно требуют нулевого значения, я бы поставил флажок рядом с полем ввода, чтобы пользователь мог включать и выключать его, чтобы увидеть соответствующее значение, равное нулю (или в более удобной для пользователя форме – нет).При включении флажка для установки поля в нулевое значение соответствующее текстовое поле должно быть отключено, и если нулевое значение уже связано, оно должно начинаться как отключенное и становиться включенным только после того, как пользователь снимет флажок с нулевым флажком.
Другие советы
Я нарушу шаблон и скажу, что всегда буду использовать NULL для строк нулевой длины по следующим причинам.
Если вы начнете детально анализировать последствия пробелов, вы должны каким-то образом гарантировать, что каждый другой разработчик читает и записывает это одинаково.
Как вы это расположите в алфавитном порядке?
Можете ли вы однозначно определить, когда пользователь пропустил ввод значения по сравнению с намеренно оставив его пустым?
Как бы вы однозначно запросили разницу?Может ли пользователь экрана запроса указать NULL или NULL?пусто, используя синтаксис стандартной формы ввода?
На практике мне никогда не запрещали читать и записывать данные, используя стандартное поведение, что неудивительно при использовании этого правила.Если мне нужно было узнать разницу, я использовал логическое поле (которое легче сопоставить с однозначными устройствами пользовательского интерфейса).В одном случае я использовал триггер для принудительного применения значения True => null, но никогда не видел, чтобы он вызывался, поскольку уровень BR эффективно отфильтровывал условие.
Если пользователь предоставляет пустую строку, я всегда рассматриваю ее как нулевую с точки зрения базы данных.Кроме того, я обычно обрезаю вводимые строки, чтобы удалить начальные/конечные пробелы, а затем проверяю их на пустые значения.Это небольшой выигрыш в базе данных с типами varchar(), а также уменьшает количество случаев поиска, поскольку мне нужно только проверить name is null
вместо name is null or name = ''
Вы также можете пойти другим путем, преобразовав null в ''.В любом случае, выберите путь и будьте последовательны.
Что вам нужно сделать, это выяснить, что поведение вы хотите.Не существует единой фиксированной алгебры интерпретации строк имен.
Подумайте о государственной машине здесь:у вас есть поля, которые имеют несколько состояний:похоже, что вы думаете о состоянии «неинициализировано», другом «намеренно пустом» и третьем с некоторым заданным значением.ВСЕ, что вы делаете, что соответствует этому назначению и согласуется с остальной частью вашей программы, будет найдено;похоже, что простое сопоставление
NULL → неинициализировано
"" → намеренно снято
имя → инициализировано.
Я стараюсь делать вещи простыми.В этом случае я бы сделал столбец имени не допускающим значения NULL и разрешил бы пробелы.В противном случае вам придется иметь дело с тремя случаями, где бы вы ни ссылались на это поле:
- Пустое имя
- Нулевое имя
- Непустое имя
Если вы выберете «пустое значение равно нулю» или «пустое значение равно пустому», то у вас останется два случая.Два случая лучше, чем три.
Чтобы дополнительно ответить на ваш вопрос:пользователь, вводящий данные, вероятно, не знает (и не должен) ничего знать о том, что такое «ноль» и как его сравнивать с «пустым».Эта проблема должна быть четко и последовательно решена в системе, а не в пользовательском интерфейсе.
Хотя ваш пример в основном предназначен для строк, я хотел бы сказать, что я использую значение null для числовых и логических полей.Баланс счета, равный 0, для меня сильно отличается от нулевого.То же самое и с логическими значениями: если люди проходят тест с множественным выбором с истинными и ложными ответами, очень важно знать, ответил ли кто-то верно или ложно, или не ответил вообще.Если не использовать значение null в этих случаях, мне потребуется дополнительная таблица или другая настройка, чтобы увидеть, ответил ли кто-то на вопрос.Например, вы можете использовать -1 для незаполненного значения 0 для ложного и 1 для истинного, но тогда вы используете числовое поле для чего-то, что по сути является логическим.
Я никогда, никогда не использовал значение NULL в рабочем коде.Пустая строка — это точное контрольное значение для пустого поля имени, номера телефона или годового дохода для любого приложения.Тем не менее, я уверен, что вы могли бы найти ему применение, но я просто думаю, что этим злоупотребляют.Если я были однако, чтобы использовать значение NULL, я думаю, что буду использовать его везде, где хочу представить пустое значение.
Я всегда использовал NULL
для неинициализированных значений, empty
для намеренно пустых значений и 0
для индикаторов выключения.
Если делать это постоянно, оно будет там, даже если я его не использую, но мне не нужно делать ничего другого, если мне нужно это различие.
Я обычно проверяю empty()
, но иногда я проверяю isset()
который оценивает false
на NULL
.Это полезно для напоминаний об ответах на определенные вопросы.Если это empty
, false
или 0
тогда на вопрос есть ответ.