Должен ли я использовать NULL или пустую строку для представления данных в столбце таблицы?
Нулевая или пустая строка - лучше ли другой, чтобы не представлять данные в столбце таблицы? (Я специально использую MySQL, но думаю, что это не зависит от системы.) Существуют ли основные преимущества / недостатки использования одного над другим или это просто предпочтение программиста?
16 ответов
Я категорически не согласен со всеми, кто говорит безоговорочно использовать NULL. Разрешение столбцу быть NULL вводит дополнительное состояние, которого у вас не было бы, если бы вы установили столбец как NOT NULL. Не делайте этого, если вам не нужно дополнительное состояние. То есть, если вы не можете придумать разницу между значением пустой строки и значением null, тогда установите для столбца значение NOT NULL и используйте пустую строку для представления пустого значения. Представлять одну и ту же вещь двумя разными способами - плохая идея.
Большинство людей, которые сказали вам использовать NULL, также привели пример, где NULL будет означать нечто иное, чем пустая строка. И в этих примерах они правы.
Однако в большинстве случаев NULL является ненужным дополнительным состоянием, которое просто заставляет программистов обрабатывать больше случаев. Как уже упоминали другие, Oracle не позволяет этому дополнительному состоянию существовать, потому что он обрабатывает NULL и пустую строку как одно и то же (невозможно сохранить пустую строку в столбце, который не допускает нулевое значение в Oracle).
Ноль. Пустая строка - это не "нет данных", это данные, которые оказываются пустыми.
Null лучше "" на самом деле представляет данные, и он не будет регистрировать то же самое в вашем коде
Ни. Представьте отсутствие данных как отсутствие кортежей в отношении.
По соображениям производительности вы можете избегать объединений в некоторых СУБД, но попытайтесь спроектировать модель так, чтобы информация, которая может отсутствовать, находилась в отдельном отношении.
В контексте модели реляционной базы данных null указывает "нет значения" или "неизвестное значение". Он существует именно для той цели, которую вы описываете.
ОБНОВЛЕНИЕ: Извините, я забыл добавить, что, хотя большинство (все?) RDMBS используют одно и то же определение для нуля, есть нюансы в том, как обрабатывается нуль. Например, MySQL и Oracle допускают наличие нескольких нулей в столбце UNIQUE (или в наборе столбцов), поскольку null не является значением и не может считаться уникальным (null!= Null). Но в последний раз, когда я использовал MS SQL Server, он допускал только один ноль. Таким образом, вам может понадобиться рассмотреть поведение РСУБД и то, будет ли данный столбец ограничен или проиндексирован.
Вот пара ссылок с сайта MySQL:
http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html
http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html
Я прочитал однажды, что NULL
значение составляет 2 бита, где в качестве пустой строки используется только 1 бит. В 99% случаев это не имеет никакого значения, но в очень большом столе, когда не имеет значения, NULL
или же ''
тогда может быть лучше использовать ''
если это правда.
Используйте правильный инструмент для работы. NULL может означать, что никакое значение не было предоставлено (пока) или это может означать, что никакое значение не применимо.
Но пустая строка тоже информация. Это может означать, что значение применимо и дано, но это пустая строка.
Разрешение столбцу содержать как NULL, так и '' дает вам возможность различать эти случаи. В любом случае, нехорошо использовать одно для обозначения другого.
Имейте в виду, что при объединении строк все, что объединено с NULL, приводит к NULL. Например: CONCAT(NULL, 'foo') возвращает NULL. Научитесь использовать функцию COALESCE(), если вы хотите преобразовать NULL в некоторое значение по умолчанию в выражении SQL.
Всегда используйте NULL. Рассмотрим разницу между "Я не знаю, что это за номер телефона этого человека" (NULL) и "этот человек оставил это поле пустым" (пусто).
В большинстве случаев ноль лучше. Вероятно, в некоторых ситуациях это мало что меняет, но их мало. Просто помните, когда вы запрашиваете field = ''
это не то же самое, что field is null
(в MySQL, по крайней мере).
NULL - это неценность, которая должна быть отнесена к темным векам, откуда она возникла. Я обнаружил, что есть нетривиальный объем программирования, необходимый для обработки особых случаев NULL, которые можно легко обработать с помощью значения по умолчанию.
Установите по умолчанию для вашего столбца пустую строку. Заставьте столбец не разрешать пустое значение, что, скорее всего, никогда не произойдет, если вы назначите значение по умолчанию. Пишите свой код блаженно, игнорируя случай, когда значение столбца равно нулю.
Одна огромная проблема, которую я всегда имел с NULL, заключается в том, что "SELECT * from tbl WHERE column = NULL" всегда будет возвращать пустой набор результатов. NULL никогда не может быть равен чему-либо, включая NULL. Специальное ключевое слово "столбец является нулевым" - единственный способ проверить, является ли что-то нулевым. Если вы отступите от нуля, тогда сравнение будет успешным: "column = ''" 7 строк возвращено.
Я сделал две основные реализации БД с нуля, где, в конце концов, я пожалел об использовании NULL. В следующий раз нет NULL для меня!
Создайте отдельную таблицу только для столбца, который может иметь значение NULL, и внешнего ключа для основной таблицы. Если в записи нет данных для этого столбца, то во второй таблице не будет записи. Это самое чистое решение, и вам не нужно беспокоиться об обработке нулей или придании особого значения пустым строкам.
Подумайте, почему в столбце нет данных. Означает ли это, что дизайн стола небрежный? Несмотря на то, что они не нравятся нулям, бывают случаи, когда они уместны (или достаточно уместны), и система обычно не умирает. Просто никогда не допускайте пустых значений во всем, что является ключом-кандидатом (первичным или альтернативным ключом).
Насколько я могу судить, Oracle не различает разницу.
select 1 from (select '' as col from dual) where col is null;
Есть одно важное исключение. Билл Карвин заявил, что "CONCAT(NULL, 'foo') приводит к NULL", что верно для большинства СУБД, но НЕ для Oracle.
Как указывал Джеймс Керран выше, Oracle выбрал этот довольно критический момент, чтобы отойти от стандартного SQL, обрабатывая NULL и пустые строки абсолютно одинаково. Хуже, чем просто обрабатывать их одинаково, однако, он может фактически исказить значение значения NULL, возвращая что-то отличное от NULL при конкатенации.
В частности, в oracle CONCAT(NULL, 'foo') выдает 'foo'. Благодаря Oracle, я теперь потерял свои нули, которые могут не иметь значения для вас, но, несомненно, имеют значение, когда данные передаются в другие СУБД для дальнейшей обработки.
Значение "без данных" в столбце должно быть представлено значением по умолчанию. Помните, что NULL означает неизвестное значение, то есть столбец может иметь значение или нет, но вы не знаете его на данный момент.
Например, в системе заявки на получение ссуды значение NULL в поле Номер водительского удостоверения означает, что заявитель или обработчик ссуды не вводили номер водительского удостоверения. Значение NULL автоматически не означает, что у заявителя нет лицензии. Он может иметь или не иметь лицензию, вы просто не знаете ее, поэтому она имеет значение NULL.
Неоднозначность заключается в строковых столбцах. Числовой столбец, очевидно, содержит ноль, если нет значения. Как вы можете представить строку без значения? В приведенном выше примере для кандидатов, у которых нет водительских прав, вы можете назначить произвольное значение по умолчанию, например, "none" или, что еще лучше, пустую строку. Просто убедитесь, что вы используете пустое значение по умолчанию в других ваших таблицах для согласованности.
Что касается вопроса о неприменении NULL в качестве принципа, существуют случаи, когда они действительно необходимы. Как те, кто активно работает со статистикой, поставщики данных обычно предоставляют вам наборы данных с неполными данными. Например, в наборе данных о ВВП на страну вы можете найти недостающие показатели ВВП за предыдущие и последующие годы. Одной из причин является то, что официальных данных за эти годы от правительства страны нет. Будет неверным делать вывод, что их ВВП равен нулю (DUH!) И показывать нулевое значение в извлеченных данных или графике. Правильное значение NULL, что означает, что у вас еще нет данных. Конечный пользователь правильно интерпретирует отсутствующие точки данных в извлеченных данных и графиках как НЕ ноль. Кроме того, это не вызовет ошибок в ваших вычислениях, особенно когда вы делаете средние значения.
Некоторые "правила", которые имеют теоретический смысл, на самом деле будут плохим или неправильным решением в вашем случае.
Я считаю значения NULL полезными для ссылочной целостности. В случае MySQL, если для поля установлено значение NOT NULL, для вставки требуются данные; в противном случае NULL является возможным значением, а ограничение внешнего ключа не применяется.
- id: первичный ключ
- product_id: FOREIGN KEY NOT NULL
- ref_id: (NULLABLE)
Область id и product_id всегда обязательна. ref_id может быть установлен в NULL. Однако, если используется любое другое значение, оно должно удовлетворять ограничению FOREIGN KEY.