Подтвердить что ты не робот

Насколько либерально я должен быть с NULL столбцами?

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

Должен ли я отмечать как NOT NULL только те столбцы, которые обязательно должны быть заполнены для строки, чтобы иметь какой-либо смысл в моем приложении?

Или я должен отмечать все столбцы, которые я намерен никогда не иметь значение null?

Каковы последствия производительности небольших и больших столбцов NOT NULL?

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

Может ли кто-нибудь с большим количеством знаний, чем я, дать мне низкую ставку?

4b9b3361

Ответ 1

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

Ответ 2

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

"Должен ли я отмечать как NOT NULL только те столбцы, которые обязательно должны быть заполнены для строки, чтобы иметь какой-либо смысл для моего приложения?"

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


EDIT:

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

Ответ 3

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

Предоставление случайным вещам NULL - рано или поздно всегда - кошмар IME. Используйте NULL осторожно и экономно - и знайте, что это значит в вашей логике.

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

Пример Le Dorfier DateOfDeath - хороший пример. NULL DateOfDeath указывает, что "еще не произошло". Теперь я могу написать представление LivingPersons WHERE DateOfDeath IS NULL.

Но что означает NULL OrderDate? Что заказ еще не был размещен? Даже если в таблице заказов есть запись? Как насчет NULL-адреса? Это те мысли, которые должны пройти через вашу голову, прежде чем позволить NULL быть ценным.

Вернуться к DateOfDeath - запрос лиц WHERE DateOfDeath > '1/1/1999' не вернет записи NULL - хотя мы логически знаем, что они должны умереть после 1999 года. Это то, что вы хотите? Если нет, тогда вам лучше включить OR DateOfDeath IS NULL в этот запрос. Если вы разрешаете всем столбцам значение NULL, вы должны думать об этом каждый раз, когда вы пишете запрос. IME, что слишком много психического налога для 10% или около того столбцов, которые на самом деле имеют законное значение, когда они являются NULL.

Ответ 4

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

Ответ 5

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

У меня есть 2 исключения:

  • Даты, в которых дата может быть неизвестна (например, DivorcedOn)
  • Дополнительные отношения с ключевыми словами foriegn (MarriedToPersonId). Хотя иногда я использовал "пустые" строки в таблице внешних ключей и делал обязательное взаимодействие (например, JobDescriptionCode)

Я также иногда использовал явные битовые поля для "unknown" / "not set" (например, JobDescriptionCode и IsEmployeed).

У меня есть несколько основных причин:

  • NULL всегда будут вызывать проблемы в числовых полях. Всегда. Всегда. Всегда. Неважно, насколько осторожен вы в какой-то точке, выберите X + Y, поскольку Total произойдет, и он вернет NULL.
  • NULL могут легко вызвать проблемы в строковых полях, обычно адресные поля (например, выберите AddrLine1 + AddrLine2 из Адресов).
  • Защита от NULL в уровне бизнес-логики - утомительная трата усилий... просто не позволяйте им в БД и вы можете сохранить 100 строк кода.

Мои предпочтительные значения по умолчанию:

  • Строки → "", также как пустая строка
  • Числа → 0
  • Даты → Сегодня или NULL (см. исключение №1)
  • Бит → false

Ответ 6

Вы можете найти Chris Date Database In Depth полезный ресурс для этих вопросов. Вы можете получить представление о своих идеях в этом интервью где он говорит, среди прочего:

Итак, да, я считаю, что SQL довольно плохой. Но вы прямо спрашиваете, недостатки. Ну, вот несколько:

  • Повторяющиеся строки
  • Нулевые
  • Порядок расположения слева направо
  • Без названия столбцов и дубликатов имен столбцов
  • Неспособность правильно поддерживать "="
  • Указатели
  • Высокая избыточность

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

Это хорошо отображает интерпретацию отношения как логическое предложение первого порядка. Это также просто здравый смысл. Когда вы не знаете адрес Боба, записывается ли в одном Rolodex:

Bob. ____

Или просто воздерживается от заполнения адресной карточки для Боба, пока у вас не будет фактического адреса для него?

Изменить: аргумент Date отображается на страницах 53-55 базы данных в глубину под заголовком раздела "" Почему Nulls запрещены "."

Ответ 7

Я наклоняюсь к NOT NULL, если не вижу другой причины - как кто-то сказал, нравится это или нет, NULL - это странный частный случай.

Один из моих фаворитов в отношении NULL:

SELECT F1 FROM T WHERE F2 <> 'OK'

... который (по крайней мере, в DB2) не будет содержать никаких строк, где f2 равно null, потому что в реляционном жаргоне (NULL < > 'OK') NULL. Но ваше намерение состояло в том, чтобы вернуть все строки не-ОК. Вам нужен дополнительный предикат ИЛИ, или вместо этого напишите F2 DISTINCT FROM 'OK' (это, в первую очередь, специальная кодировка).

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

Joe Celko пишет об этом в SQL For Smarties - ловушка использования NULL в приложении заключается в том, что его смысл, ну, undefined. Это может означать неизвестное, неинициализированное, неполное, неприменимое - или, как в приведенном выше глухом примере, означает ли это "ОК" или "нет"? "

Ответ 8

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

Разрешить nulls if-and-only - если значение null в эта колонка будет иметь конкретную что означает ваше приложение.

Несколько общих значений для null:

  • Все, что приходит непосредственно от пользователя
    • Здесь null означает, что "пользователь не вводил"
    • Для этих столбцов лучше разрешить нули, иначе вы просто получите вход типа [email protected]
  • Внешние ключи для отношений "0 или 1"
    • null означает "нет связанной строки"
    • Таким образом, разрешить null для этих столбцов
    • Этот противоречивый, но это мое мнение.

В общем случае, если вы не можете придумать полезное значение для null в столбце, оно должно быть NOT NULL. Вы всегда можете изменить его на nullable позже.

Пример того, что у меня получилось:

create table SalesOrderLine (
    Id int identity primary key,
    -- a line must have exactly one header:
    IdHeader int not null foreign key references SalesOrderHeader, 
    LineNumber int not null, -- a line must have a line number
    IdItem int not null, -- cannot have null item
    Quantity decimal not null, -- maybe could sell 0, but not null
    UnitPrice decimal not null, -- price can be 0, but not null
    -- a null delivery address means not for delivery:
    IdDeliveryAddress int foreign key references Address, 
    Comment varchar(100), -- null means user skipped it
    Cancelled bit not null default (0) -- true boolean, not three-state!
    Delivered datetime, -- null means not yet delivered
    Logged datetime not null default (GetDate()) -- must be filled out
)

Ответ 9

Я бы согласился с дорфиром.

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

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

Ответ 10

Придерживайтесь NOT NULL на все, пока кто-то не скрипит от боли. Затем удалите его по одной колонке за раз, насколько это неохотно. Избегайте нулей в вашей БД сколько угодно, сколько сможете.

Ответ 11

Лично я думаю, что вы должны пометить столбцы как Null или не null, основываясь на том, какие данные они содержат, если есть подлинное требование для того, чтобы данные всегда были там, и были ли данные всегда известны во время вход. Пометка столбца как null, когда пользователи не имеют данных, заставит затем составлять данные, которые делают все ваши данные бесполезными (это, как вы заканчиваете с такими неактивными данными, как поле электронной почты, содержащее "[email protected]" "). Если вам не требуется что-то, что должно быть там, чтобы процесс работал (скажем, ключевое поле, чтобы показать, какой заказчик сделал заказ) одинаково глупо. Null vice not null - это проблема целостности данных в сердце, делайте то, что наиболее важно для сохранения ваших данных.

Ответ 12

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

С точки зрения производительности, быстрее не беспокоиться о NULLS. С точки зрения дизайна использование NULL - это простой способ узнать, что элемент никогда не был заполнен. Полезными примерами являются столбцы "UpdateDateTime". NULL означает, что элемент никогда не обновлялся.

Лично я разрешаю NULL в большинстве ситуаций.

Ответ 13

Каковы последствия производительности небольших и больших столбцов NOT NULL?

Это может указывать на очевидное, но, когда столбец имеет значение NULL, каждая запись потребует 1 дополнительный бит памяти. Таким образом, столбец BIT будет потреблять на 100% больше хранилища при его нулевом значении, тогда как UNIQUEIDENTIFIER будет потреблять на хранение всего 0,8% больше, если он является нулевым.

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

Ответ 14

Использование "Not Null" или "Null" должно основываться главным образом на ваших конкретных требованиях к стойкости.

Наличие значения Nullable означает, что существует два или три состояния (три состояния с битовыми полями)

Например; если бы у меня было поле бит, которое называлось "IsApproved" , а значение было задано на более позднем этапе, чем вставка. Тогда есть три состояния:

  • 'IsApproved' Не ответил
  • "IsApproved" одобрен
  • "IsApproved" не одобрен

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

Ответ 15

Любой столбец с нулевым значением является нарушением третьей нормальной формы.

Но это не ответ.

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

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

Когда у вас есть столбец, который содержит один из вариантов выбора или нулевой (без выбора), обычно рекомендуется иметь определенное значение для "no choice made", а не для столбца с нулевым значением. Эти типы столбцов часто участвуют в объединениях.