Причина, чтобы не использовать номер Nullable в Oracle?


12

Наша компания взаимодействует с другой компанией-разработчиком программного обеспечения для совместного проекта, и нам сказали, что, если конкретное значение не должно отображаться, мы должны передать значение -5000 (их произвольное значение часового); причина в том, что ни один числовой столбец в их базе данных Oracle не поддерживает нулевые значения по рекомендации их (теперь уже бывшего) Oracle dev. Эта компания также пишет подавляющее большинство своего кода на VB6 (медленно переходя на VB.NET, что является еще одной темой для другого дня ...). Из чистого любопытства, есть ли веская причина для этой рекомендации? Я не могу думать ни о ком на моей стороне.

--- редактировать

Спасибо всем за отзывы. Я задал тот же вопрос на CodeProject.com ( ссылка ) и получил очень похожие отзывы. Похоже, единственное время, когда можно было бы оправдать эту практику, связано с внешними ключами, и я могу сказать, что они не используют внешние ключи где-либо в системе. Разработчик, который сделал это определение (я работал в этой компании), обладает значительно большим опытом, чем я, поэтому я хотел убедиться, что для этого не было веской причины, прежде чем начнется насмешка.


2
Вы имеете в виду, кроме "это то, что указывает их API"?
Роберт Харви

Да, мне более интересно, почему их API в первую очередь указывает это; есть ли причина для этой практики, или это просто какое-то безумие?

3
Безумие высочайшего порядка!
Philᵀᴹ

Ответы:


17

Реально требование сумасшедшее. Однако, как и все великие безумные идеи, он, вероятно, основан на самородке потенциальной разумности, вырванном далеко из контекста людьми, которые не понимают основополагающего обоснования.

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

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


+1 и дополнительный код для проверки магических значений не может использовать такие хорошо известные функции, как COALESCE()- так что это становится еще сложнее.
ypercubeᵀᴹ

И значения должны храниться в любом индексе в этом столбце. Индексы не должны хранить нулевые значения.
Трипп Кинетикс

15

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

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

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

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Они не хотят писать или забывают в будущем написать это, поэтому они придумали решение сделать все NULLS -5000. Волшебным образом их оригинальный запрос обрабатывает NULL без каких-либо изменений. Они не понимают, что теперь тот, кто хочет исключить эти значения, должен написать это:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

Или, если они хотели эти значения и ищут более высокий диапазон:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Они также могут не осознавать, что следующее больше не будет иметь смысла:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Вместо этого человек должен помнить магическую ценность. С каждым используемым типом данных они должны помнить больше магических значений, например, 1/1 // 1900, «Z», -5000. Кроме того, когда магическое значение находится в данных, они также должны помнить альтернативные магические значения.

Таким образом, для одного конкретного случая это упрощает код за счет других случаев, не говоря уже о дисковом пространстве, размере индекса, разборе запросов, согласованности и т. Д.


8

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

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


5

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

Совсем другое дело сказать, что наше приложение не должно принимать значение NULL для некоторых (или даже всех) столбцов. Это разумная и эффективная практика, и есть хорошо документированные преимущества недопущения пустых значений (например, ключи и индексы и статистические вычисления). Однако присвоение значения «сидеть на месте» нуля совсем не одно и то же. Это стержень для вашей собственной спины, так как вы должны сначала выбрать значение, которое никогда не будет использоваться, отфильтровать это значение, как если бы оно было нулевым, и помните, что не следует использовать его в расчетах и ​​сводках, и удалить его из внешних каналов данных. , По крайней мере, это так же плохо, если использовать нулевое значение для представления фактического значения. Это то, что вы говорите себе, что избегаете, но это не так.

Большинство проблем, которые вызывают нулевые значения, если их понять, могут быть решены (лучшая нормализация, функциональные или растровые индексы или простое WHERE x NOT NOT NULL). Считаете ли вы, что на каком-то большом Telco или в Amazon на ежемесячном собрании по производительности некоторые администраторы баз данных обрисовывают этот великий план, чтобы немного ускорить запросы к их огромным наборам данных, «заменив ноль на произвольное значение, что-то вроде -5000, или что-то еще» Я открыт по стоимости ... ». Или вы думаете, что они тратят свое время на то, чтобы улучшить дизайн приложений, чтобы отфильтровать нежелательные значения NULL, и оптимизировать запросы на основе полученных данных ? Хорошо, хорошо, может быть, ежемесячное собрание немного оптимистично, но всякий раз, когда они случаются, я могу заверить вас, что «Замена нулей на -5000 (или что-то еще) для лучшего API» не является пунктом повестки дня.

Для меня хорошо сказать, что я не приму отсутствующие данные (у вас должен быть возраст, цена или код региона или что-то еще), а иногда даже хорошо сказать, что для этого столбца есть значение по умолчанию, которое будет введено, если Вы не кладете что-то еще. Нельзя назначать значение, равное нулю. Подумайте о полях второго имени в качестве примера. Иногда их не будет, потому что родители слишком ленивы, чтобы заполнить все поля. Добавляем ли мы «нет» или «отсутствует» или «неизвестно» в наши данные, чтобы улучшить наш поиск? Нет, потому что могут быть странные люди, которые меняют свои имена на эти значения, и поэтому, когда мы распечатываем данные, мы не знаем, должны ли мы их включать или нет. Это простой, но далеко идущий пример. Мы знаем о NULL и имеем предсказуемые встроенные функции для работы с ним. Вы не можете кодировать это лучше.

Если ни один ответ (или NULL) не является действительным ответом на ваш запрос ввода, не допускайте его в приложении или в базе данных, если это хороший ответ, вы должны разрешить его как в приложении, так и в вашей базе данных, и иметь дело с это как верный ответ. Если она является частью набора действительных ответов, ваша база данных должна быть предназначена для ее хранения. В конце концов, вы не говорите «эй», поля чисел настолько скучны, что позволяют хранить числа в каплях и использовать изображения диких животных для представления каждого числа, потому что это орехи (круто, но орехи). Мы также не решаем, что нам не нравится буква B, и, как какой-то ужасный кошмар на Сезам-стрит, заменим ее символом # в наших данных. Если B не является ответом, который мы хотим, мы говорим пользователю «Эй, вы не можете поставить B здесь». Так почему же по-другому относиться к нулю?

Поэтому избегайте нулевых значений, которые вам не нужны на уровне приложения, и обрабатывайте их в своей базе данных, где вы их принимаете, иначе как giraffe + giraffe = hippo, ваш бессмысленный спор данных доставит вам неприятности.


2
Мои родители не были ленивыми, и у меня, кстати, нет второго имени. Не все люди живут в США.
ypercubeᵀᴹ

1
Это должен был быть беззаботный пример, без обид. Есть, конечно, много людей без отчеств (первая точка) по многим вполне обоснованным причинам (основная точка). Нуль в этом столбце ничего не говорит о том, почему он пропал. Не уверен насчет своего геополитического угла - я не живу в США, но на самом деле имею второе имя. Сложно делать предположения на основе недостающих данных, я полагаю.

Без обид. Я проголосовал за твой ответ на самом деле. Я думаю, что вы достигли цели, указав, что есть разница между тем, чтобы не принимать / не разрешать Null в базе данных, и заменять Nulls магическим значением.
ypercubeᵀᴹ

5
Я был бы рад, если бы мое второе имя было "-5000"! : D
Philᵀᴹ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.