Стандартное использование 'Z' вместо NULL для представления отсутствующих данных?
вне аргумента о том, должны ли когда-либо использоваться нули: я отвечаю за существующую базу данных, которая использует NULL для обозначения "отсутствующих или никогда не вводимых" данных. Он отличается от пустой строки, Что означает "пользователь установил это значение, и они выбрали "пустой"."
другой подрядчик по проекту твердо стоит на" NULLs не существует для меня; я никогда не использую NULL, и никто другой не должен, либо " сторона аргумента. Однако меня смущает то, что с тех пор команда подрядчика признает разницу между" отсутствующим/никогда не вводимым "и" намеренно пустым или указанным пользователем как неизвестным", они используют один символ" Z "во всем своем коде и хранимых процедурах для представления" отсутствующего/никогда не вводимого " с тем же значением, что и NULL во всей остальной части базы данных.
хотя наш общий клиент попросил изменить это, и я поддержал этот запрос, команда цитирует это как "стандартную практику" среди DBAs far более продвинутые, чем я; они неохотно изменяются, чтобы использовать нули, основанные только на моей невежественной просьбе. Итак, может кто-нибудь помочь мне преодолеть мое невежество? Есть ли какой-либо стандарт, или небольшая группа лиц, или даже один громкий голос среди экспертов SQL, который выступает за использование " Z " вместо NULL?
обновление
У меня есть ответ от исполнителя добавить. Вот что он сказал, Когда клиент просит специального значения, которые должны быть удалены, чтобы разрешить значения NULL в Столбцах, без данные:
в основном, я разработал базу данных, чтобы избежать нулей, когда это возможно. Вот обоснование:
*NULL в поле string [VARCHAR] никогда не требуется, потому что пустая строка (нулевой длины) предоставляет точно такую же информацию.
*значение NULL в целочисленном поле (например, значение ID) может быть обработано с помощью значения, которое никогда не встречается в данных (например, -1 для целочисленного идентификатора поле.)
*значение NULL в поле даты может легко вызвать осложнения при вычислении даты. Например, в логике, которая вычисляет различия дат, такие как разница в днях между [RecoveryDate] и [OnsetDate], логика взорвется, если одна или обе даты равны нулю, если только не будет сделано явное допущение для обеих дат, являющихся нулевыми. Это дополнительная работа и дополнительная обработка. Если даты" default "или" placeholder " используются для [RecoveryDate] и [OnsetDate] (например, "1/1/1900") , математические вычисления могут показать "необычные" значения-но логика даты не взорвется.
обработка NULL традиционно была областью, где разработчики допускают ошибки в хранимых процедурах.
в мои 15 лет в качестве DBA, я нашел, что лучше избегать нулей, где это возможно.
Это, кажется, подтверждает в основном негативную реакцию на этот вопрос. Вместо применения принятый подход 6NF к проектированию нулей, специальные значения используются, чтобы " избежать нулей, где это возможно."Я опубликовал этот вопрос с открытым умом, и я рад, что узнал больше о дебатах "NULLs полезны / NULLs-зло", но теперь мне вполне комфортно называть подход "специальных ценностей" полным нонсенсом.
пустая строка (нулевой длины) предоставляет точно такую же информацию.
нет, это не так; в существующей базе данных мы изменяются, NULL означает "никогда не вводится", а пустая строка означает"введено как пустое".
обработка NULL традиционно была областью, где разработчики допускают ошибки в хранимых процедурах.
да, но эти ошибки были сделаны тысячи раз тысячами разработчиков, и уроки и предостережения для избежания этих ошибок известны и документированы. Как уже упоминалось здесь: принимаете ли вы или отклоняете нули, представление отсутствует значения-это решена проблема. Нет необходимости изобретать новое решение только потому, что разработчики продолжают делать легко преодолеваемые (и легко идентифицируемые) ошибки.
в качестве сноски: я был DBE и разработчиком более 20 лет (что, безусловно, достаточно времени для меня, чтобы знать разницу между инженером базы данных и администратором базы данных). На протяжении всей моей карьеры я всегда был в лагере" NULLs are useful", хотя я знал с этим не согласились несколько очень умных людей. Я крайне скептически относился к подходу "особых ценностей", но недостаточно хорошо разбирался в академиках "Как избежать нулевого правильного пути", чтобы занять твердую позицию. Я всегда люблю узнавать новое-и мне еще многому предстоит научиться после 20 лет. Спасибо всем, кто внес свой вклад в это полезное обсуждение.
8 ответов:
уволить вашего подрядчика.
ладно, серьезно, это не стандартная практика. Это можно увидеть просто потому, что все СУБД, с которыми я когда-либо работал, реализуют NULL, логику для NULL, учитывают NULL во внешних ключах, имеют разное поведение для NULL в COUNT и т. д. и т. д.
Я бы на самом деле утверждал, что использование " Z " или любого другого держателя места хуже. Вам все еще требуется код для проверки 'Z'. Но вам также нужно документировать, что " Z "не означает "Z", это означает что-то еще. И вы должны убедиться, что такая документация читать. И что тогда произойдет, если 'Z' когда-либо станет действительной частью данных? (Например, поле для инициала?)
на базовом уровне, даже не обсуждая действительность NULL vs 'Z', я бы настаивал на том, что подрядчик соответствует стандартным практикам, которые существуют в вашей компании, а не его. Установление его стандартной практики в среде с альтернативной стандартной практикой вызовет путаницу, обслуживание накладные расходы, неправильное понимание, и в конце концов увеличились затраты и ошибки.
EDIT
есть случаи, когда использование альтернативы NULL допустимо, на мой взгляд. Но только там, где это уменьшает код, а не создает специальные случаи, которые требуют учета.
я использовал это для привязанных к дате данных, например. Если данные действительны между датой начала и датой окончания, код можно упростить, не имея нулевых значений. Вместо нулевой начальная дата может быть заменена на '01 Jan 1900', а нулевая конечная дата может быть заменена на'31 Dec 2079'.
Это все еще может изменить поведение от того, что можно ожидать, и поэтому следует использовать с осторожностью:
WHERE end-date IS NULLбольше не давать данные, которые все еще действительны- вы только что создали свою собственную ошибку тысячелетия
- etc.
Это эквивалентно реформированию абстракций таким образом, что все свойства всегда могут иметь действительное значение. Он заметно отличается от неявного кодирования конкретного значения в произвольно выбранные значения.
тем не менее, уволить подрядчика.
это легко одно из самых странных мнений, которые я когда-либо слышал. Использование магического значения для представления " нет данных "вместо NULL означает, что каждый фрагмент кода, который у вас есть, должен будет после обработки результатов учитывать/отбрасывать значения"нет данных"/" 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 и поэтому избегает его использования.
если домен допускает пропущенные значения, то использование NULL для представления "undefined" совершенно нормально (вот для чего он существует). Единственным недостатком является то, что код, который потребляет данные, должен быть написан для проверки на наличие нулей. Я всегда так делал.
Я никогда не слышал (и видел на практике) использование " Z " для представления отсутствующих данных. Что касается "подрядчик цитирует это как" стандартную практику "среди баз данных", может ли он представить некоторые доказательства этого утверждения? Как @ЦМР упомянуто, вам также нужно документально подтвердить, что " Z "не означает "Z": как насчет a ?
Как Аарон Алтон и многие другие, я считаю, что нулевые значения являются неотъемлемой частью дизайна базы данных, и должны использоваться там, где это необходимо.
даже если вам каким-то образом удастся объяснить всем вашим нынешним и будущим разработчикам и базам данных о "Z" вместо NULL, и даже если они все прекрасно кодируют, вы все равно будете путать оптимизатор, потому что он не будет знать, что вы это приготовили.
использование специального значения для представления NULL (которое уже является специальным значением для представления NULL) приведет к искажению данных. например, так много вещей произошло 1-Jan-1900, что это выбросит способность оптимизатора понимаю, что фактический диапазон дат, которые действительно имеют отношение к вашему приложению.
Это похоже на решение менеджера: "носить галстук плохо для производительности, поэтому мы все будем носить клейкую ленту вокруг наших шей. Проблема решена."
Я никогда не слышал о широком использовании
'Z'заменить наNULL.(кстати, я бы не особенно хотел работать с подрядчиком, который говорит вам в лицо, что они и другие "продвинутые" DBAs намного более осведомлены и лучше вас.)
+=================================+ | FavoriteLetters | +=================================+ | Person | FavoriteLetter | +--------------+------------------+ | 'Anna' | 'A' | | 'Bob' | 'B' | | 'Claire' | 'C' | | 'Zaphod' | 'Z' | +---------------------------------+как бы ваш подрядчик интерпретировал данные из последней строки?
вероятно, он выбрал бы другое "магическое значение" в этой таблице, чтобы избежать столкновения с реальные данные
'Z'? Это означает, что вы должны помнить несколько магических значений, а также Какой из них используется где... как это лучше, чем иметь только один волшебный токенNULL, и нужно помнить трехзначные логические правила (и подводные камни), которые идут с ним?NULLпо крайней мере стандартизирован, в отличие от вашего подрядчика'Z'.мне не особо нравится
NULL, но бездумно подставляя его с фактическим значением (или еще хуже, с несколькими фактическими значениями) везде почти определенно хуже, чемNULL.позвольте мне повторить мой комментарий выше здесь для лучшей видимости: если вы хотите прочитать что-то серьезное и обоснованное людьми, которые против
NULL, Я бы рекомендовал короткую статью "как обрабатывать недостающую информацию без использования значения" (ссылки на PDF из главная страница третьего Манифеста).
ничто в принципе не требует нулей для правильного проектирования базы данных. На самом деле существует множество баз данных, разработанных без использования null, и есть много очень хороших дизайнеров баз данных и целых команд разработчиков, которые разрабатывают базы данных без использования null. В общем, это хорошая вещь, чтобы быть осторожным о добавлении нулей в базу данных, потому что они неизбежно приводят к неправильным или неоднозначным результатам позже.
Я не слышал, чтобы использование Z называлось "стандартной практикой" в качестве значение заполнителя вместо нулей, но я ожидаю, что ваш подрядчик ссылается на концепцию sentinel values В общем, которые иногда используются в дизайне базы данных. Однако гораздо более распространенным и гибким способом избежать нулей без использования "фиктивных" данных является их простое проектирование. Разложите таблицу так, чтобы каждый тип факта был записан в таблицу, которая не имеет "дополнительных", неопределенных атрибутов.
в ответ на замечания подрядчиков
- пустая строка NULL
- пустая строка требует хранения 2 байта + смещение чтения
- NULL использует нулевое растровое изображение = быстрее
- идентичность не всегда начинается с 1 (Зачем тратить половину вашего диапазона?)
вся концепция ошибочна в соответствии с большинством других ответов здесь
хотя я никогда не видел " Z "как магическое значение для представления null, я видел, что" X " используется для представления поля, которое не было заполнено. Тем не менее, я только когда-либо видел это в одном месте, и мой интерфейс к нему не был базой данных, а скорее XML-файлом... поэтому я не был бы готов использовать этот аргумент для общей практики.
обратите внимание, что мы должны обрабатывать " X " специально, и, как упоминалось Dems, мы должны документировать его, и люди были смущены им. В нашу защиту, это навязано нам внешним поставщиком, а не то, что мы сами приготовили!
Comments