Нули в реляционной базе данных в порядке? - PullRequest
68 голосов
/ 02 октября 2008

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

Ответы [ 33 ]

6 голосов
/ 22 апреля 2009

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

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

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

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

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

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

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

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

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

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

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

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

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

Опять же, книга Селко - хорошее изложение предмета.

6 голосов
/ 02 октября 2008

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

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

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

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

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

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

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

5 голосов
/ 02 октября 2008

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

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

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

4 голосов
/ 02 октября 2008

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

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

3 голосов
/ 02 октября 2008

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

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

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

3 голосов
/ 02 октября 2008

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

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

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

3 голосов
/ 02 октября 2008

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

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

3 голосов
/ 02 октября 2008

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

Предположим, у вас есть таблица счетов-фактур со столбцом «PaidDate» со значением даты. Что вы указали в этой колонке до того, как счет был оплачен (при условии, что вы заранее не знаете, когда он будет оплачен)? Это не может быть пустой строкой, потому что это недопустимая дата. Не имеет смысла давать ему произвольную дату (например, 01.01.1900), потому что эта дата просто неверна. Кажется, единственное разумное значение - NULL, потому что оно не имеет значения.

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

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

3 голосов
/ 06 октября 2008

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

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

2 голосов
/ 02 октября 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...