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

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

технически, говоря языком СУБД, null не является значением; это отсутствие ценности, например неизвестный

Matt Rogish 02.10.2008 21:05

Существует мнение, что схемы тоже должны быть полностью нормализованы. Ни одна из школ не попала в реальный мир. :)

Chris Noe 02.10.2008 23:27

Если мы не должны использовать NULL, почему РСУБД позволяют нам вообще использовать NULL? В NULL нет ничего плохого, если вы знаете, как с ними бороться. Создание отдельных таблиц для хранения столбцов с нулевыми значениями в каждом сценарии является чрезмерным заблуждением.

Fr0zenFyr 13.08.2013 11:31

Нули - это артефакт импеданса между СУБД и реальностью. Это масштабный системный прием для преодоления этого сопротивления. Решение не в том, чтобы избавиться от нулей, что непрактично в контексте СУБД. Решение - новые виды баз данных.

Brad Thomas 05.03.2014 20:27

Фактически импеданс находится между caos (реальностью) и человеческими побуждениями к семантике. Enteties, структуры, типы или что-то еще, все они подвержены изменениям. Разберитесь с полиморфной природой любого типа - имейте дело с нулями.

Teson 29.10.2015 13:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
76
5
33 111
33

Ответы 33

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

технически, говоря языком СУБД, null не является значением; это отсутствие ценности, например неизвестный

Matt Rogish 02.10.2008 21:03

Зафиксированный. Быстрый переход к Википедии показывает, что NULL - это «маркер», а не значение.

Patrick McElhaney 02.10.2008 21:07

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

dvb 25.12.2010 23:27

Без объяснения причин этот ответ может стать бесполезным, если кто-то другой опубликует противоположное мнение. Например, если кто-то публикует утверждение типа «Нулевые маркеры не подходят. На самом деле, нет»., как этот ответ поможет читателю выбрать два противоположных мнения? Рассмотрите вариант редактироватьing, чтобы лучше соответствовать рекомендациям Как ответить

gnat 22.06.2015 20:04

Это не объясняет, что такое «маркер». (И гораздо проще четко и правильно адресовать нулевую семантику, просто используя тот факт, что null - это значение, которое специально обрабатывается синтаксисом и операторами SQL - так, как SQL и риторика апологета null.)

philipxy 11.03.2019 01:44

Абсолютно нормально с null.

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

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

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

-Адам

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

Steven A. Lowe 06.10.2008 19:04

Вы не можете находиться в первой нормальной форме со столбцами, допускающими значение NULL. Одна ссылка, которая явно заявляет об этом, - en.wikipedia.org/wiki/Database_normalization#First_normal_fo‌ rm «Проще говоря, таблица с уникальным ключом и без каких-либо столбцов, допускающих значение NULL, находится в 1NF».

Adam Davis 06.10.2008 21:03

Хорошо, но тогда я бы возразил, что обеспечение того, чтобы ваша БД была в 1NF, не обязательно так ценно, особенно если это будет стоить вам удобства использования и ясности. (Не поймите меня неправильно, нормализация, конечно, в целом желательна ... но ее соблюдение с точки зрения исключения нулей кажется контрпродуктивным.)

Beska 22.04.2009 19:25

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

Adam Davis 22.04.2009 20:02

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

Adam Davis 22.04.2009 20:03

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

Beska 23.04.2009 00:10

Ссылки: CJ Date довольно хорошо известен в реляционных базах данных. Он является главным сторонником «нулевых значений, считающихся вредными», например. см. здесь dcs.warwick.ac.uk/~hugh/TTM/Missing-info-without-nulls.pdf

MarkJ 11.12.2009 04:13

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

ANeves thinks SE is evil 14.04.2010 14:08

@sr pt - Да, это глупо. Существует баланс между соблюдением хороших практик нормализации и разумным подходом к проектированию базы данных. С обеих сторон есть крайности - база данных может быть слишком нормализована.

Adam Davis 14.04.2010 16:50

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

npeterson 09.04.2012 23:03

Нулевые значения могут быть полезны при использовании наследования одной таблицы, которое является самым простым и быстрым способом (и рекомендовано Мартином Фаулером) использовать наследование таблиц.

Neil McGuigan 18.02.2013 23:16

Просто выйти и сказать, что «все НУЛИ - это дьявол», вызвало много проблем. Ненужные неприятности. Один парень прочитал, насколько плохи NULLS, и пришел в ярость, когда дело дошло до проектирования баз данных. Например. у вас есть автомобили. У некоторых автомобилей есть свойства, например Запасное колесо, которое есть у типа CAR, но не у типа BOAT. Итак, что у нас есть таблица для VehiclesWithSpareWheels + VehiclesWithoutSpareWheels, чтобы мы могли сохранить нулевой столбец? Безумие. Индексирование, многие союзы - это программный эквивалент Углеводы, черт возьми, и теперь все банят.

Peter PitLock 21.12.2015 09:52

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

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

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

Taptronic 02.10.2008 21:11

Более или менее поддерживает то, что вы сказали для акцента. ;-)

Taptronic 02.10.2008 21:12

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

Bob Probst 02.10.2008 21:19

Если чего-то не хватает, значит, в какой-то таблице должна отсутствовать строка. «NULL» не «отсутствует», «NULL» означает «что-нибудь». Это стоит повторить.

Constantin 14.10.2008 12:44

Если чего-то не хватает, значит, в какой-то таблице должна отсутствовать строка. «NULL» не «отсутствует», «NULL» означает «что-нибудь». Это стоит повторить. (повторяется)

simon 04.11.2009 18:31

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

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

По-разному.

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

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

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

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

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

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

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

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

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

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

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

«Нуль - лучший способ представить такой сценарий». Я не согласен. Учитывая (first_name, middle_initial, last_name), что означает NULL в middle_initial? Не ясно; либо мы не знаем, либо его не существует. NULL не говорит нам, какой именно.

Dave 02.10.2008 21:25

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

Mark Brady 02.10.2008 21:35

У вас может быть таблица адресов, но там нет ничего для ссылки на таблицу Person. Мне это больше нравится.

Joe Phillips 02.10.2008 21:56

@Dave: Неважно, Почему значения нет, только то, что его нет. Что бы вы предложили в качестве допустимого значения, исключая нули, для значения, которое неизвестно (по какой-либо причине)?

Erik Forbes 02.10.2008 21:58

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

Cade Roux 03.10.2008 07:04

Неверно, что нет «другого правильного способа представить отсутствие данных». Действительно, согласно реляционной алгебре, использование нулей неверно. Правильный способ - иметь отдельные таблицы для каждого необязательного поля, как предлагает Кейд. Как отмечали другие, это быстро становится громоздким.

Dour High Arch 03.10.2008 20:54

В Oracle пустая строка фактически равна NULL :)

Camilo Díaz Repka 06.10.2008 08:49

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

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

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

Хорошая точка зрения. Это хорошо для многоуровневой настройки базы данных / приложения, поскольку позволяет приложению интерпретировать значение null. Я уверен, что администраторы баз данных хотели бы, чтобы это было иначе. :)

Matias Nino 02.10.2008 21:35

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

Jonathan Allen 06.10.2008 09:18

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

6eorge Jetson 06.10.2008 10:09

+1, потому что это известный аргумент против нулей в схемах баз данных, обнародованный CJ Date (я не обязательно с этим согласен), например. его книга Введение в системы баз данных

MarkJ 11.12.2009 04:17

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

Sam Watkins 17.01.2017 10:31

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

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

В этом случае я бы использовал логический объект.

James A. N. Stauffer 02.10.2008 21:24

Чтобы создать thedailywtf.com, вам также понадобится значение FileNotFound ;-)

kurosch 25.10.2008 02:04

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

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

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

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

Matias Nino 02.10.2008 21:37

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

мой язык хорош с нулевыми примитивами :)

TheSoftwareJedi 02.10.2008 21:14

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

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

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

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

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

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

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

Хороший аргумент в пользу зарезервированных значений для столбцов за пределами нормального диапазона столбца. Это позволит нам иметь разнообразную самодокументирующуюся гибкость в дизайне столбцов с константами, такими как перечисления, для представления «НЕИЗВЕСТНО», «БЕЗ ДАТЫ СМЕРТИ» и т. д. Без бесконечных ограничений и флагов.

Cade Roux 03.10.2008 07:10

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

Sam Watkins 17.01.2017 10:45

@SamWatkins Я думаю, что мы имеем в виду "иметь в виду" двумя разными способами.

David Aldridge 17.01.2017 16:44

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

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

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

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

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

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

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

У меня не было бы таблицы счетов со столбцом «PaidDate» именно из-за проблемы NULL. Вместо этого у меня были бы таблицы «счет», «к оплате» и «к получению» с внешним ключом, связывающим счета-фактуры с кредиторской задолженностью. Это также решает проблему, когда счет оплачивается несколькими частями.

benjismith 06.10.2008 10:03

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

Nick 22.04.2009 19:25

Есть еще одна альтернатива использованию «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));

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

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

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

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

Если вы не используете COALESCE, если столбец Любые содержит значение НУЛЕВОЙ, вы получите возвращенное значение НУЛЕВОЙ.

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

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

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

Связанный вопрос: Как обеспечить соблюдение правил целостности данных в моей базе данных?

Сначала я начал с множества небольших таблиц с почти нулевыми полями nullalbe. Затем я узнал о свойстве IsDiscriminator LINQ to SQL и о том, что LINQ to SQL поддерживает только наследование одной таблицы. Поэтому я переделал ее в единую таблицу с множеством полей nullalbe.

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

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

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

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

Steven A. Lowe 06.10.2008 09:31

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

Dour High Arch 20.11.2009 03:07

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

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

Выберите c.id, c.lastname, ....... от клиента c левый присоединиться к клиенту номер телефона cpn на c.id = cpn.customerid оставил присоединиться к клиенту по адресу ca на c.id = ca.customerid левый присоединиться к customerphonenumber2 cpn2 на c.id = cpn2.customerid и т. д., т. д. и т. д.

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

Для простоты определите NULL и придерживайтесь его. Я использую его для обозначения «значение в этом поле в настоящее время неизвестно». Это значит то и ТОЛЬКО это. Если вам нужно, чтобы это означало что-то еще, ТАКЖЕ, тогда вам нужно пересмотреть свою модель данных.

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

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

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

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

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

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

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

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

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

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

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

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

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

  5. В базе данных Oracle хранилась пустая строка.

Вот несколько советов о том, когда следует избегать NULL:

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

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

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

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

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

pingu 06.12.2013 18:40

Возможно, поможет гипотетический пример. Есть таблица под названием «Человек» с одной строкой на человека. Первый столбец - это «id» и используется в качестве первичного ключа. Есть столбец "SpouseId". Когда есть супруг (а), он содержит внешний ключ, который ссылается на Person.id супруга. Когда нет супруга, он содержит NULL.

Walter Mitty 06.12.2013 19:22

Спасибо за оперативное разъяснение! Могу ли я внести небольшие изменения в ваш пример, чтобы увидеть, можно ли по-прежнему использовать NULL? Таблица людей с полем профессии. Допустимым занятием может быть «Priest» или «Nun», так что для них SpouseId всегда будет NULL. Короче говоря, допустимо ли использовать NULL, если не все записи потенциально могут иметь значение, отличное от NULL?

pingu 06.12.2013 20:23

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

Walter Mitty 07.12.2013 20:50

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

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

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

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

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

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

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

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

У нулей есть еще немало других тонкостей. В книге «SQL для умников» Джо Селко есть целая глава на эту тему, и это хорошая книга, которую в любом случае стоит прочитать. Вот несколько примеров мест, где нули являются хорошим решением:

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

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

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

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

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

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

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

И снова книга Селко хорошо раскрывает эту тему.

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

where bitfield in (1,0)

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

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

Теперь, если исключаемая таблица содержит нуль и 1, это переводится как:

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

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

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

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

Sam Watkins 17.01.2017 10:43

It seems that if null is valid within the context of the attribute, then it should be allowed.

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

This is very common in Java where object references are often null.

Есть школа мысли, которая гласит нулевые ссылки там тоже плохие. Та же проблема: что значит null иметь в виду?

IIRC, Java имеет как «null», так и «неинициализированный» (хотя для последнего нет синтаксиса). Таким образом, Гослинг осознал безрассудство использования «нуль» для любого вида «не имеет значения». Но зачем останавливаться на только два?

Null означает любое значение null, определенное для этого атрибута. Я мог бы, например, определить нулевое отчество как отсутствие отчества. Но значение null необходимо определить. Это то же самое, что и любое другое значение. Использование аргумента «что это означает» означает, что любое значение ошибочно. Если я вижу поле типа int, что значит 3? Хорошо, вы проверите документацию и посмотрите, что такое кодировка.

Steve Kuo 22.04.2009 22:21

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

-1, 01.01.1000, 01.12.1999 и? будет достаточно и без искажающего разум кода, необходимого для обработки этих неприятных значений NULL.

А что произойдет, если ваше специальное значение - допустимое значение (например, -1)?

Steve Kuo 03.06.2010 23:03

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

Pieter B 11.04.2014 17:32

@PieterB Даже если он больше не работает с нулями, его будет легче отлаживать и исправлять, потому что вы использовали нули, 0 или -1 отлично подходят, пока вы не придете для настройки своих внешних ключей, тогда вам внезапно ваше магическое число должно быть 385 чтобы учесть это, когда вам действительно удалось вставить новую ссылку, но это нормально, вы избежали неприятного нуля. До тех пор, пока кто-то не отправит счет «мистеру Системе», и тогда людям придется выяснять, откуда пришли все счета, назначенные Системе. NULL присутствует на всех современных языках и означает, что это не объект, попытка выставить счет на null не сработает.

scragar 16.09.2014 19:59

@scragar Возможно, я сформулировал свой комментарий немного странно, но я думаю, что мы согласны.

Pieter B 17.09.2014 00:14

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

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

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

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

Спасибо Naveen

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

Другие вопросы по теме