Стандартное использование "Z" вместо NULL для представления отсутствующих данных?

За пределами аргумента о том, следует ли использовать NULL: я несу ответственность за существующую базу данных, которая использует NULL для обозначения "отсутствующих или никогда не вводимых" данных. Он отличается от пустой строки, что означает, что "пользователь установил это значение, и они выбрали" empty "."

Другой подрядчик по проекту твердо уверен в том, что "NULL не существуют для меня, я никогда не использую NULL, и никто другой не должен, либо" стороны аргумента ". Однако меня смущает то, что, поскольку команда-подрядчик ДОЛЖНА признать разницу между" отсутствующим/никогда не введенным "и" намеренно пустым или указанным пользователем как неизвестным ", они используют один символ" Z "на протяжении всего своего кода и хранимых процедур для представляют" отсутствующие/никогда не введенные" с тем же значением, что и NULL во всей остальной базе данных.

Хотя наш общий клиент попросил изменить это, и я поддержал этот запрос, команда ссылается на это как "стандартную практику" среди администраторов баз данных, гораздо более продвинутых, чем я; они неохотно меняются на использование NULL на основе моего невежественного запроса. Так может ли кто-нибудь помочь мне преодолеть мое невежество? Есть ли стандарт или небольшая группа людей или даже один громкий голос среди экспертов SQL, который выступает за использование "Z" вместо NULL?

Update

У меня есть ответ от подрядчика, чтобы добавить. Вот что он сказал, когда клиент попросил удалить специальные значения, чтобы разрешить NULL в столбцах без данных:

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

• NULL в поле строки [VARCHAR] никогда не требуется, поскольку пустая (нулевая) строка предоставляет точно такую ​​же информацию.

• NULL в целочисленном поле (например, значение ID) может обрабатываться с использованием значения, которое никогда не будет происходить в данных (например, -1 для целочисленного поля IDENTITY).

• NULL в поле даты может легко вызвать осложнения при расчете дат. Например, в логике, которая вычисляет различия по дате, такие как разница между днями между [RecoveryDate] и [OnsetDate], логика взорвется, если одна или обе даты будут NULL - если явно не будет дано четкое разрешение для обеих дат NULL. Эта дополнительная работа и дополнительная обработка. Если для [RecoveryDate] и [OnsetDate] (например, "1/1/1900" ) используются даты "default" или "placeholder", математические вычисления могут показывать "необычные" значения, но логика даты не взорвется.

Обработка NULL традиционно была областью, где разработчики допускают ошибки в хранимых процедурах.

В мои 15 лет как администратор базы данных, я нашел, что лучше избегать NULL, где это возможно.

Это, похоже, подтверждает негативную реакцию на этот вопрос. Вместо применения принятого подхода 6NF к разработке NULL специальные значения используются для "избежания NULL, где это возможно". Я опубликовал этот вопрос с открытым сознанием, и я рад, что узнал больше о том, что "NULLs являются полезными /NULLs являются злыми" дебатами, но теперь я довольно удобен, обозначая подход "специальных ценностей", чтобы быть полной ерундой.

пустая (нулевая) строка предоставляет точно такую ​​же информацию.

Нет, это не так; в существующей базе данных мы модифицируем, NULL означает "никогда не вводится", а пустые строки означают "введено как пустое".

Обработка NULL традиционно была областью, где разработчики ошибались в хранимых процедурах.

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


В качестве сноски: я уже более 20 лет являюсь разработчиком DBE и разработчиком (для меня, безусловно, достаточно времени, чтобы узнать разницу между инженером базы данных и администратором базы данных). На протяжении всей моей карьеры я всегда был в лагере "NULLs полезны", хотя я знал, что несколько очень умных людей не согласились. Я очень скептически относился к подходу "специальных ценностей", но не достаточно хорошо разбирался в науках "Как избежать NULL на правильном пути", чтобы сделать устойчивую позицию. Мне всегда нравится изучать новые вещи, и у меня еще есть много возможностей учиться через 20 лет. Спасибо всем, кто внес свой вклад в это полезное обсуждение.

Ответ 1

Устраните вашего подрядчика.

Хорошо, серьезно, это не стандартная практика. Это можно увидеть просто потому, что все СУБД, с которыми я когда-либо работал с NULL NULL, логикой для NULL, учитывали NULL во внешних ключах, имеют различное поведение для NULL в COUNT и т.д. И т.д.

Я бы действительно утверждал, что использование "Z" или любого другого владельца места хуже. Вам по-прежнему требуется код для проверки "Z" . Но вам также нужно документировать, что "Z" не означает "Z" , это означает что-то другое. И вы должны убедиться, что такая документация читается. И тогда, что произойдет, если "Z" когда-нибудь станет действительной частью данных? (Например, поле для начального?)

На базовом уровне, даже не обсуждая действительность NULL vs 'Z', я бы настаивал на том, что подрядчик соответствует стандартным практикам, которые существуют в вашей компании, а не его. Установление его стандартной практики в среде с альтернативной стандартной практикой приведет к путанице, накладным расходам на техническое обслуживание, неправильному пониманию и, в конечном счете, увеличению затрат и ошибок.


ИЗМЕНИТЬ

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

Я использовал это, например, для данных, привязанных к дате. Если данные действительны между датой начала и датой окончания, код можно упростить, не имея значений NULL. Вместо этого начальная дата NULL может быть заменена на "01 января 1900 года", а конечная дата NULL может быть заменена на "31 декабря 2079 года".

Это все еще может изменить поведение от того, что можно ожидать, и поэтому его следует использовать с осторожностью:

  • WHERE end-date IS NULL больше не дают данные, которые все еще действительны
  • Вы только что создали свою собственную ошибку тысячелетия
  • и др.

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

Тем не менее, увольте подрядчика.

Ответ 2

Это легко одно из самых странных мнений, которые я когда-либо слышал. Использование магического значения для представления "нет данных", а не "NULL" означает, что каждый фрагмент кода, который у вас есть, должен будет обрабатывать результаты для учетной записи/отбрасывать значения "no-data" / "Z".

NULL является особенным из-за того, что база данных обрабатывает его в запросах. Например, возьмите эти два простых запроса:

select * from mytable where name = 'bob';
select * from mytable where name != 'bob';

Если name всегда имеет значение NULL, оно, очевидно, не будет отображаться в результатах первого запроса. Что еще более важно, и не будет отображаться во втором запросе. NULL не соответствует ничего, кроме явного поиска NULL, как в:

select * from mytable where name is NULL;

И что происходит, когда данные могут иметь Z как действительное значение? Скажем, вы храните кого-то среднего начального? Будет ли Захари Зонкас с теми людьми, у которых нет среднего начального? Или ваш подрядчик придумал еще одно волшебное значение, чтобы справиться с этим?

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

Ответ 3

Если домен разрешает пропущенные значения, то использование NULL для представления 'undefined' отлично (это то, для чего оно существует). Единственным недостатком является то, что код, который потребляет данные, должен быть записан для проверки NULL. Так я всегда это делал.

Я никогда не слышал (или видел на практике) использование "Z" для представления отсутствующих данных. Что касается "подрядчика, то он цитирует это как" стандартную практику "среди администраторов баз данных", может ли он предоставить некоторые доказательства этого утверждения? Как упоминалось в @Dems, вам также нужно документировать, что "Z" не означает "Z" : как насчет столбца MiddleInitial?

Как Aaron Alton и многие другие, я считаю, что значения NULL являются неотъемлемой частью дизайна базы данных и должны использоваться там, где это необходимо.

Ответ 4

Даже если вам как-то удастся объяснить всем вашим нынешним и будущим разработчикам и администраторам баз данных о "Z" вместо NULL, и даже если они все правильно кодируют, вы все равно путаете оптимизатор, потому что он не будет знать, что вы приготовил это.

Использование специального значения для представления NULL (которое уже является специальным значением для представления NULL) приведет к перекос в данных. например Так было много вещей, произошедших с 1 января по 1900 год, что он выкинет способность оптимизатора понять тот фактический диапазон дат, который действительно имеет отношение к вашему приложению.

Это похоже на решение менеджера: "Ношение галстука плохо для производительности, поэтому мы все будем носить маскировочную ленту вокруг шеи. Проблема решена".

Ответ 5

Я никогда не слышал о широко распространенном использовании 'Z' в качестве замены для NULL.

(Кстати, мне не особо хотелось бы работать с подрядчиком, который говорит вам, что они и другие "продвинутые" администраторы баз данных гораздо лучше осведомлены и лучше вас.)

 +=================================+
 |  FavoriteLetters                |
 +=================================+
 |  Person      |  FavoriteLetter  |
 +--------------+------------------+
 |  'Anna'      |  'A'             |
 |  'Bob'       |  'B'             |
 |  'Claire'    |  'C'             |
 |  'Zaphod'    |  'Z'             |
 +---------------------------------+

Как ваш контрактор будет интерпретировать данные из последней строки?

Вероятно, он выбрал бы другое "волшебное значение" в этой таблице, чтобы избежать столкновения с реальными данными 'Z'? Это означает, что вам нужно будет запомнить несколько магических значений, а также, какой из них используется там, где... как это лучше, чем иметь только один магический токен NULL, и помнить о трехзначных логических правилах (и ловушках), которые идут с этим? NULL по крайней мере стандартизирован, в отличие от вашего подрядчика 'Z'.

Мне не особенно нравится NULL, но бездумно подставляя его фактическим значением (или, что еще хуже, с несколькими фактическими значениями), везде почти определенно хуже, чем NULL.

Позвольте мне повторить мой вышеприведенный комментарий здесь для лучшей видимости: если вы хотите прочитать что-то серьезное и обоснованное людьми, которые против NULL, я бы порекомендовал короткую статью "Как обрабатывать недостающую информацию без использования NULL" (ссылки на PDF из Третий манифест Домашняя страница).

Ответ 6

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

Я не слышал, чтобы использование Z называлось "стандартной практикой" в качестве значения-заполнителя вместо нулей, но я ожидаю, что ваш подрядчик ссылается на концепцию значений часовых в целом, которые иногда используются в дизайне базы данных. Однако гораздо более распространенный и гибкий способ избежать нулей без использования данных "dummy" - это просто их дизайн. Разложите таблицу таким образом, чтобы каждый тип факта записывался в таблицу, у которой нет "лишних", неуказанных атрибутов.

Ответ 7

В ответ на комментарии подрядчиков

  • Пустая строка < > NULL
  • Пустая строка требует хранения 2 байтов + считывание смещения
  • NULL использует null bitmap = быстрее
  • ИДЕНТИФИКАЦИЯ не всегда начинается с 1 (зачем тратить половину вашего диапазона?)

Вся концепция ошибочна, как и большинство других ответов здесь

Ответ 8

В то время как я никогда не видел "Z" в качестве магического значения для представления null, я видел, что "X" используется для представления поля, которое не было заполнено. Тем не менее, я только когда-либо видел это в одном месте, и мой интерфейс к нему не был базой данных, а скорее XML файлом... поэтому я не был бы готов использовать этот аргумент для обычной практики.

Обратите внимание, что нам нужно обрабатывать "X" специально, и, как упоминалось в Dems, нам нужно документировать его, и люди его смутили. В нашей защите это навязывается нам внешним поставщиком, а не тем, что мы приготовили сами!