Нуль в реляционной базе данных в порядке?

Там думают, что нулевые значения не должны допускаться в реляционной базе данных. То есть атрибут таблицы (столбец) не должен допускать нулевые значения. Исходя из фона разработки программного обеспечения, я действительно этого не понимаю. Кажется, что если значение null является допустимым в контексте атрибута, оно должно быть разрешено. Это очень часто встречается в Java, где ссылки на объекты часто равны нулю. Не имея обширного опыта работы с базами данных, я задаюсь вопросом, не хватает ли я чего-то здесь.

Ответ 1

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

Это попытка убедиться, что все данные действительны и оценены.

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

-Adam

Ответ 2

Нулевые маркеры в порядке. Действительно, они есть.

Ответ 3

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

  • Значение "Nothing" или "Empty set"
  • Нет значения, которое имеет смысл для этого поля.
  • Значение неизвестно.
  • Значение еще не введено.
  • Значение представляет собой пустую строку (для баз данных, которые не различают нули и пустые строки).
  • Некоторое специфическое для приложения значение (например, "Если значение равно null, тогда используйте значение по умолчанию".)
  • Произошла ошибка, в результате чего у поля было нулевое значение, если это действительно не так.

Некоторые дизайнеры схем требуют, чтобы все значения и типы данных имели четко определенные интерпретации, поэтому нули являются плохими.

Ответ 4

Это зависит.

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

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

С другой стороны, если вы не разрешаете NULL и имеете специальные зарезервированные значения для определенных случаев (вместо флагов), например -1 для числа детей, когда это действительно неизвестно, вам необходимо обратиться к ним в аналогичным образом, с точки зрения соглашений, документации и т.д.

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

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

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

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

Ответ 5

Существует несколько разных возражений против использования NULL. Некоторые из возражений основаны на теории базы данных. Теоретически нет разницы между теорией и практикой. На практике существует.

Верно, что полностью нормализованная база данных может обойтись без NULLS. Любое место, где значение данных должно быть опущено, - это место, где вся строка может быть оставлена ​​без потери информации.

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

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

Данные могут отсутствовать в местоположении по разным причинам. Вот несколько:

  • В этом контексте данные неприменимы. например имя супруга для одного человека.

  • Пользователь формы ввода данных оставил поле пустым, и приложение не требует ввода в поле.

  • Данные копируются в базу данных из другой базы данных или файла, и в источнике отсутствуют данные.

  • Существует необязательная взаимосвязь, закодированная в внешнем ключе.

  • Пустая строка хранилась в базе данных Oracle.

Вот некоторые рекомендации о том, когда следует избегать NULLS:

Если в ходе обычного ожидаемого программирования автору запросов необходимо написать много ISNULL, NV, COALESCE или аналогичный код, чтобы заменить допустимое значение для NULL. Иногда лучше делать замену в хранилище, при условии, что хранится "реальность".

Если счетчики, вероятно, будут отключены, потому что считаются строки, содержащие NULL. Часто это можно устранить, просто выбрав count (MyField) вместо count (*).

Вот одно место, где вы по golly лучше привыкаете к NULLS и программируете соответственно: всякий раз, когда вы начинаете использовать внешние объединения, например LEFT JOIN и RIGHT JOIN. Весь внешний вид внешнего соединения в отличие от внутреннего соединения - это получение строк, когда отсутствуют некоторые совпадающие данные. Отсутствующие данные будут указаны как NULLS.

Моя нижняя строка: не упускайте теорию, не понимая ее. Но учитесь, когда отходить от теории, а также как следовать ей.

Ответ 6

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

Если что-то "не существует", вы должны использовать NULL вместо пустой строки или другого флага.

Ответ 7

Вместо того, чтобы записывать все проблемы NULL и tristate vs логической логики и т.д. - я предлагаю этот подробный совет:

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

  • Поскольку вы задаете этот вопрос, вы должны быть очень осторожны в том, как вы приближаетесь к NULL. Там много неочевидных ловушек. Если вы сомневаетесь, не используйте NULL.

Ответ 8

Я бы сказал, что Nulls обязательно нужно использовать. Нет другого правильного способа представления недостатка данных. Например, было бы неправильно использовать пустую строку для представления отсутствующей строки адреса, иначе было бы неправильно использовать 0 для представления отсутствующего элемента данных возраста. Потому что и пустая строка, и 0 являются данными. Null - лучший способ представить такой сценарий.

Ответ 9

Существует другая альтернатива использованию "N/A" или "N/K" или пустой строки - отдельной таблицы.

например. если мы можем или не можем знать номер телефона клиента:

CREATE TABLE Customer (ID int PRIMARY KEY, Name varchar(100) NOT NULL, Address varchar(200) NOT NULL);
CREATE TABLE CustomerPhone (ID int PRIMARY KEY, Phone varchar(20) NOT NULL, CONSTRAINT FK_CustomerPhone_Customer FOREIGN KEY (ID) REFERENCES Customer (ID));

Если мы не знаем номер телефона, мы просто не добавляем строку во вторую таблицу.

Ответ 10

Не стоит недооценивать сложность, которую вы создаете, создавая поле NULLable. Например, следующее выражение where выглядит так, как оно будет соответствовать всем строкам (бит может быть только 1 или 0, правильно?)

where bitfield in (1,0)

Но если битовое поле NULLable, оно пропустит некоторые. Или возьмите следующий запрос:

select * from mytable
where id not in (select id from excludetable)

Теперь, если excludetable содержит null и a 1, это означает:

select * from mytable
where id <> NULL and id <> 1

Но "id < > NULL" является ложным для любого значения id, поэтому это никогда не вернет строки. Это захватывает даже опытных разработчиков баз данных за счет сюрпризов.

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

Ответ 11

Это огромная банка червей, потому что NULL может означать так много вещей:

  • Нет даты смерти, потому что человек все еще жив.
  • Нет номера сотового телефона, потому что мы не знаем, что это такое или даже если оно существует.
  • Нет номера социального страхования, потому что этот человек знает, что у него его нет.

Некоторые из них можно избежать путем нормализации, некоторые из них можно избежать из-за наличия значения в этом столбце ( "N/A" ), некоторые из них могут быть смягчены за счет наличия отдельного столбца для объяснения присутствия из NULL ( "N/K", "N/A" и т.д.).

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

Из-за прежней причины вы найдете случаи, когда нуль является неизбежным.

Из-за последней причины вы все равно должны сделать все возможное, чтобы свести к минимуму их количество.

Независимо от того, всегда используйте ограничения NOT NULL для защиты от нулей, где требуется значение.

Ответ 12

Лучше всего знать о Нормальных Формах - это то, что они являются руководствами и руководствами, которые не следует упрямо придерживаться. Когда мир академических наук сталкивается с реальным миром, вы редко находите много выживших воинов адемии.

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

Как друг любит говорить: "Не позволяйте совершенству быть врагом добра". Подумайте, Вольтер также сказал это. 8)

Ответ 13

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

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

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

  • Нули могут выпадать из подсчетов, что, возможно, не является семантикой, которую вы желаете.

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

Существует множество других тонкостей для нулей. Joe Celko SQL для Smarties содержит целую главу на эту тему и является хорошей книгой и стоит читать в любом случае. Некоторыми примерами мест, где нули являются хорошим решением, являются:

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

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

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

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

  • "Не записано" значения в полях кода с FK по отношению к справочной таблице. Используйте значение-заполнитель, чтобы вы (или какой-то случайный бизнес-аналитик спускались по дорожке) не случайно бросали строки из результирующих наборов при выполнении запроса к базе данных.

  • Поля описания, в которых ничего не было введено, - null string ('') отлично подходит для этого. Это сохраняет необходимость рассматривать нули как частный случай.

  • Дополнительные столбцы в системе отчетов или хранилища данных. В этой ситуации сделайте строку-заполнитель для "Not Recorded" в измерении и присоединитесь к этому. Это упрощает запросы и отлично работает с специальными инструментами отчетности.

Опять же, книга Целько - хорошее отношение к этому вопросу.

Ответ 14

В соответствии с строгой реляционной алгеброй нули не нужны. Однако для любого практического проекта они необходимы.

Во-первых, многие реальные данные неизвестны или неприменимы, а nulls хорошо реализуют это поведение. Во-вторых, они делают взгляды и внешние соединения более практичными.

Ответ 15

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

Или вы можете установить значения по умолчанию (требуя, чтобы код обрабатывал эти значения по умолчанию). Вы можете предположить, что все строки пустые, а не нулевые, например, в вашей модели.

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

Ответ 16

В базу данных значение null переводится как "У меня нет значения для этого". Это означает, что (интересно), логический столбец, который допускает null, является совершенно приемлемым и появляется во многих схемах базы данных. Напротив, если у вас есть логическое значение в вашем коде, которое может иметь значение "true", "false" или "undefined", вы, скорее всего, увидите, что ваш код рано или поздно закончится: d)

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

Ответ 17

Нули с ними сложно работать, но в некоторых случаях они имеют смысл.

Предположим, что у вас есть таблица счетов с столбцом "PaidDate", который имеет значение даты. Что вы помещаете в эту колонку до того, как счет был оплачен (если вы не знаете заранее, когда он будет оплачен)? Это не может быть пустая строка, потому что это не действительная дата. Не имеет смысла давать ему произвольную дату (например, 1/1/1900), потому что эта дата просто неверна. Кажется, единственное разумное значение NULL, потому что оно не имеет значения.

Работа с нулями в базе данных имеет несколько проблем, но базы данных справляются с ними хорошо. Реальные проблемы - это когда вы загружаете нули из своей базы данных в код приложения. То, что я обнаружил, что все труднее. Например, в .NET дата в строго типизированном наборе данных (имитирующая структуру БД) является типом значения и не может быть нулевым. Поэтому вам придется создавать обходные пути.

Избегайте нулевых значений, если это возможно, но не исключайте их из-за того, что они имеют действительное использование.

Ответ 18

Я думаю, вы смешиваете концептуальное моделирование данных с помощью моделирования физических данных.

В CDM, если объект имеет необязательное поле, вы должны подтипировать объект и создать новый объект, если это поле не равно нулю. Что теория в CDM

В физическом мире мы делаем всевозможные компромиссы для реального мира. В реальном мире NULLS более чем хороши, они необходимы

Ответ 19

Я согласен со многими ответами выше, а также считаю, что NULL можно использовать, когда это необходимо, в нормализованном дизайне схемы, особенно там, где вы, возможно, захотите избежать использования какого-либо "магического числа" или значения по умолчанию, которое в поворот, может ввести в заблуждение!

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

Ответ 20

Один раз, если вы используете базу данных Oracle. Если вы сохраните пустую строку в столбце типа CHAR, тогда Oracle будет принуждать значение NULL без запроса. Поэтому довольно сложно избежать значений NULL в строковых столбцах в Oracle.

Если вы используете значения NULL, научитесь использовать команду SQL COALESCE, особенно со строковыми значениями. Затем вы можете запретить использование значений NULL в вашем языке программирования. Например, представьте себе человека, имеющего имя FirstName, MiddleName и FamilyName, но вы хотите вернуть одно поле;

  SELECT FullName = COALESCE(FirstName + ' ', '') + COALESCE(MiddleName+ ' ', '') + COALESCE(FamilyName, '') FROM Person

Если вы не используете COALESCE, если столбец any содержит значение NULL, вы получите NULL.

Ответ 21

Технически, nulls являются незаконными в реляционной математике, на которой основана реляционная база данных. Поэтому из чисто технической, семантической реляционной модели точки зрения нет, они не в порядке.

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

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

Ответ 22

NULL пород. Если в некоторых случаях это не было необходимо, SQL не имел бы IS NULL и IS NOT NULL в качестве специальных случаев. NULL является корнем концептуального универсального, все остальное НЕ является NULL. Используйте NULL свободно, когда возможно, что значение данных будет отсутствовать, но не пропущено. Значения по умолчанию могут компенсировать только NULL, если они абсолютно правильны все время. Например, если у меня однобитовое поле "IsReady", это может иметь смысл для этого поля иметь значение по умолчанию false и NULL не допускается, но это неявно утверждает, что мы знаем, что все, что еще не готово, когда на самом деле у нас нет таких знаний. Скорее всего, в сценарии рабочего процесса лицо, которое решает, готовое или не просто не имело шансов вступить в свое мнение, так что дефолт ложного может быть действительно опасным, заставляя их игнорировать решение, которое, как представляется, имеет были сделаны, но фактически были дефолтами.

как в сторону, и, ссылаясь на средний пример, у моего отца не было среднего имени, поэтому его средний начальный результат был бы NULL - не пустым, пространством или звездочкой - кроме армии, где его средним начальным был NMI = Нет Начальное. Как это глупо?

Ответ 23

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

Ответ 24

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

Ответ 25

Лично я считаю, что нули следует использовать только в том случае, если вы используете это поле в качестве внешнего ключа для другой таблицы, чтобы символизировать, что эта запись не ссылается ни на что в другой таблице. Кроме этого, я считаю, что нулевые значения на самом деле очень сложны при программировании логики приложения. Поскольку нет прямого представления нулевой базы данных в большинстве языков программирования для многих типов данных, это приводит к созданию большого количества кода приложения, чтобы справиться со значением этих нулевых значений. Когда БД встречает нулевое целое число и пытается, например, добавить к нему значение 1 (aka null + 1), база данных вернет значение null, так как именно так определяется логика. Однако, когда язык программирования пытается добавить null и 1, он обычно генерирует исключение. Таким образом, ваш код заканчивается проверкой того, что делать, когда значение равно null, что часто просто приравнивается к преобразованию в 0 для чисел, пустой строке для текста и некоторой нулевой дате (1900/1/1?) Для полей даты.

Ответ 26

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

Во всей простоте определите NULL и придерживайтесь ее. Я использую его для обозначения "значение в этом поле пока неизвестно". Это значит, и ТОЛЬКО это. Если вам нужно, чтобы это означало что-то еще AS WELL, вам нужно пересмотреть свою модель данных.

Ответ 27

null означает, что значение не равно 0, если вы видите 0, вы не знаете значения, если вы видите нуль, вы знаете, что это недостающее значение

Я думаю, что нули намного яснее, 0 и '' запутывают, поскольку они явно не показывают намерение сохраненного значения

Ответ 28

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

Просто для того, чтобы сказать, как вы можете иметь имя, отчество, фамилию для каждого человека. (Второе имя и Фамилия не являются обязательными, тогда в этом случае для вас доступны NULL) а также как вы можете иметь Факс, Бизнес-телефон, Офисный телефон для всех в списке блога.

NULLS - это хорошо, и вы должны правильно обрабатывать их при поиске. В SQL Server 2008 существует концепция разреженных столбцов, в которой вы также можете избежать пространства, используемого для NULL.

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

Спасибо Нэвин

Ответ 29

Это абсолютно нормально с нулевым значением.

Ответ 30

Все сводится к нормализации в сравнении с простотой использования и проблемами производительности.

Если вы собираетесь придерживаться полных правил нормализации, вы собираетесь написать материал, который выглядит так:

Выберите c.id, c.lastname,....... от клиента c left join clientphonenumber cpn на c.id = cpn.customerid left join customeraddress ca на c.id = ca.customerid left join customerphonenumber2 cpn2 на c.id = cpn2.customerid etc, etc, etc