Я помню, как читал эту статью о дизайне базы данных, и я также помню, что сказано, что у вас должны быть свойства поля NOT NULL. Я не помню, почему это было так.
Все, о чем я могу думать, это то, что, как разработчику приложения, вам не нужно проверять NULL и возможное несуществующее значение данных (например, пустую строку для строк).
Но что вы делаете в случае дат, даты и времени (SQL Server 2008)? Вы должны будете использовать какую-нибудь историческую дату или дату с дном.
Есть идеи по этому поводу?
database-design
null
Томас Стрингер
источник
источник
Ответы:
Я думаю, что вопрос плохо сформулирован, поскольку формулировка подразумевает, что вы уже решили, что значения NULL плохие. Возможно, вы имели в виду "Должны ли мы разрешить NULL?"
В любом случае, вот мое мнение: я думаю, что NULL - это хорошая вещь. Когда вы начинаете предотвращать NULL только потому, что «NULL плохие» или «NULL трудные», вы начинаете создавать данные. Например, что если вы не знаете дату моего рождения? Что вы собираетесь поместить в колонку, пока не узнаете? Если вы что-то похожи на множество людей, отличных от NULL, вы собираетесь ввести 1900-01-01. Теперь меня поместят в гериатрическую палату и, вероятно, мне позвонят из местной местной новостной станции, поздравив меня с долгой жизнью, спросив мои секреты такой долгой жизни и т. Д.
Если можно ввести строку там, где возможно, что вы не знаете значение столбца, я думаю, что NULL имеет гораздо больше смысла, чем выбор какого-либо произвольного значения токена для представления факта, что он неизвестен - значение, которое другие будут должны уже знать, перепроектировать, или спросить вокруг, чтобы выяснить, что это значит.
Однако баланс существует - не каждый столбец в вашей модели данных должен быть обнуляемым. В форме часто присутствуют необязательные поля или фрагменты информации, которые иначе не будут собраны во время создания строки. Но это не значит, что вы можете отложить заполнение всех данных. :-)
Также возможность использования NULL может быть ограничена важными требованиями в реальной жизни. Например, в области медицины важно знать, почему значение неизвестно. Является ли сердечный ритм NULL, потому что не было пульса, или потому что мы еще не измерили его? В таком случае, можем ли мы поместить NULL в столбец сердечного ритма и иметь примечания или другой столбец с NULL-причиной?
Не бойтесь NULL, но будьте готовы узнать или диктовать, когда и где они должны использоваться, а когда и где они не должны.
источник
birth_date
которой вы храните даты рождения? Если дата рождения неизвестна, просто не вводите дату рождения вbirth_date
. Нули - это катастрофа.1900-01-01
чтобы избежать значения даты и времени NULL? Хорошо, тогда. Кроме того, NULL = неизвестно и неизвестно = ложно. Я не уверен, какие проблемы это может вызвать, кроме того, что люди не рождаются, зная об этом (как будто они не рождаются, зная много вещей, присущих сложной СУБД). Опять махаем руками и говорим "Проблема! Бедствие!" не делает это так.Установленные причины:
NULL не является значением и поэтому не имеет встроенного типа данных. Нули нуждаются в специальной обработке повсеместно, когда код, который в противном случае опирается на фактические типы, также может получить нетипизированный NULL.
NULL нарушает двухзначную (знакомую True или False) логику и требует трехзначную логику. Это гораздо сложнее даже правильно реализовать, и, конечно, плохо понимают большинство администраторов баз данных и почти все не администраторы баз данных. Как следствие, это положительно вызывает много тонких ошибок в приложении.
Смысловое значение какой - либо конкретной NULL остается приложением , в отличие от фактических значений.
Семантика, такая как «не применимо», «неизвестно» и «страж», встречается часто, и есть и другие. Они часто используются одновременно в одной и той же базе данных, даже в одном и том же отношении; и, конечно, неясные и неразличимые и несовместимые значения.
Они не нужны для реляционных баз данных , как утверждается в «Как обрабатывать недостающую информацию без нуля» . Дальнейшая нормализация является очевидным первым шагом, чтобы попытаться избавиться от таблицы NULL.
Это не означает, что NULL никогда не должен быть разрешен. Это действительно утверждает , что есть много причин , чтобы запретить NULL там , где это возможно.
Важно отметить, что в нем говорится о том, что он очень старается - за счет лучшего проектирования схем, более совершенных механизмов баз данных и даже более совершенных языков баз данных - сделать возможным более частое избегание NULL.
Фабиан Паскаль отвечает на ряд аргументов в «Null Nullified» .
источник
Я не согласен, нули являются важным элементом дизайна базы данных. Как вы уже упоминали, альтернативой может быть распространение известных значений, представляющих отсутствующие или неизвестные. Проблема заключается в том, что null так широко неправильно понимается и, как следствие, используется ненадлежащим образом.
IIRC, Кодд предположил, что текущая реализация нуля (то есть отсутствует / отсутствует) может быть улучшена за счет наличия двух нулевых маркеров, а не одного: «не присутствует, но применимо» и «не присутствует и не применимо». Не могу представить, как это улучшит реляционный дизайн.
источник
null
и пользовательскую многозначную логику, чтобы идти с ними: pПозвольте мне начать с того, что я не администратор баз данных, я разработчик наизусть, и я поддерживаю и обновляю наши базы данных в соответствии с нашими потребностями. При этом у меня был тот же вопрос по нескольким причинам.
Я провожу очень много времени, просматривая множество ответов, комментариев, статей и советов по всему Интернету. Излишне говорить, что большая часть информации была примерно такой же, как и ответ @ AaronBertrand. Именно поэтому я почувствовал необходимость ответить на этот вопрос.
Во-первых, я хочу установить что-то прямое для всех будущих читателей ... Значения NULL представляют неизвестные данные, а не неиспользуемые данные. Если у вас есть таблица сотрудников, которая имеет поле даты увольнения. Нулевое значение в дате прекращения действия объясняется тем, что это поле является обязательным в будущем, которое в настоящее время неизвестно. Каждому сотруднику, активному или уволенному, в определенный момент будет добавлена дата в это поле. Это, на мой взгляд, единственная причина для поля Nullable.
При этом одна и та же таблица сотрудников, скорее всего, будет содержать некие данные аутентификации. В корпоративной среде распространено, что сотрудники будут перечислены в базе данных для HR и бухгалтерского учета, но не всегда имеют или нуждаются в деталях аутентификации. Большинство ответов заставят вас поверить, что все эти поля можно обнулить или, в некоторых случаях, создать для них учетную запись, но никогда не отправлять им учетные данные. Первый из них заставит вашу команду разработчиков написать код для проверки на NULL и соответствующим образом с ними справиться, а второй представляет огромный риск для безопасности! Учетные записи, которые еще никогда не использовались в системе, только увеличивают количество возможных точек доступа для хакера, плюс они занимают ценное пространство базы данных для чего-то, что никогда не используется.
Учитывая приведенную выше информацию, лучший способ справиться с обнуляемыми данными, которые БУДУТ использоваться, - это разрешить обнуляемые значения. Это печально, но это правда, и ваши разработчики будут ненавидеть вас за это. Второй тип обнуляемых данных должен быть помещен в связанную таблицу (IE: учетная запись, учетные данные и т. Д.) И иметь отношение «один к одному». Это позволяет пользователю существовать без учетных данных, если они не нужны. Это устраняет дополнительный риск безопасности, ценное пространство базы данных и обеспечивает намного более чистую базу данных.
Ниже приведена очень упрощенная структура таблицы, показывающая как обязательный обнуляемый столбец, так и отношение «один к одному».
Я знаю, что немного опоздал на вечеринку, так как этот вопрос задавался много лет назад, но, надеюсь, это поможет пролить некоторый свет на эту проблему и то, как лучше всего с ней бороться.
источник
TerminationDate
в записях сотрудников не было, но имелась таблица, дляTerminatedEmployee
которой сотрудники перемещаются (не копируются) приложением после их увольнения. Очевидно, что это хорошо работает с таблицей Account, потому что в таблице не будет связанной учетной записиTerminatedEmployee
. Если вам все еще нужны телефонные номера, я бы поменял внешние ключи, чтобы таблицы сотрудников и уволенных сотрудников имели идентификатор номера телефона, а не наоборот.Помимо всех проблем с NULL, сбивающих с толку разработчиков, у NULL есть еще один очень серьезный недостаток: производительность
Пустые столбцы - это катастрофа с точки зрения производительности. Рассмотрим целочисленную арифметику в качестве примера. В нормальном мире без NULL «легко» векторизовать целочисленную арифметику в коде ядра СУБД с использованием инструкций SIMD для выполнения практически любых вычислений на скоростях, превышающих 1 строку на цикл ЦП. Однако, как только вы вводите NULL, вам нужно обработать все особые случаи, которые создает NULL. Современные наборы команд ЦП (читай: x86 / x64 / ARM и логика GPU) просто не оснащены для эффективной работы.
Рассмотрим разделение в качестве примера. На очень высоком уровне это логика, которая вам нужна с ненулевым целым числом:
С NULL это становится немного сложнее. Вместе с
b
вами понадобится индикатор, еслиb
он нулевой и аналогично дляa
. Чек теперь становится:Арифметика NULL значительно медленнее работает на современном процессоре, чем ненулевая арифметика (в 2-3 раза).
Становится хуже, когда вы вводите SIMD. С SIMD современный процессор Intel может выполнять 4 x 32-разрядные целочисленные деления в одной инструкции, например:
Теперь есть способы обработки NULL и в SIMD, но это требует использования большего количества векторов и регистров ЦП и некоторой умной битовой маскировки. Даже при хороших уловках снижение производительности целочисленной арифметики NULL возрастает в 5-10 раз медленнее даже для относительно простых выражений.
Нечто подобное выше относится к агрегатам и, в некоторой степени, к объединениям.
Другими словами: существование NULL в SQL - это несоответствие импеданса между теорией баз данных и фактическим дизайном современных компьютеров. Существует довольно веская причина, по которой NULL сбивает с толку разработчиков - поскольку целое число не может быть NULL в большинстве вменяемых языков программирования - это просто не то, как работают компьютеры.
источник
Интересные вопросы.
Это сложнее, чем это. Ноль имеет несколько различных значений, и одна действительно важная причина, по которой во многих столбцах не допускается использование пустых значений, заключается в том, что когда столбец равен нулю, это означает одну-единственную вещь (а именно то, что он не отображался во внешнем соединении). Кроме того, он позволяет устанавливать минимальные стандарты ввода данных, что действительно полезно.
Это иллюстрирует проблему с нулями сразу, а именно, что значение, хранящееся в таблице, может означать либо «это значение не применяется», либо «мы не знаем». Со строками пустая строка может служить «это не относится», но с датами и временем такого соглашения нет, потому что нет действительного значения, которое условно означает это. Обычно там вы застряли, используя NULL.
Есть способы обойти это (добавив больше связей и объединений), но они создают те же проблемы семантической ясности, что и наличие в базе данных NULL. Для этих баз данных я бы не беспокоился об этом. Вы просто ничего не можете с этим поделать.
РЕДАКТИРОВАТЬ: Одна из областей, где NULL являются обязательными, это внешние ключи. Здесь они обычно имеют только одно значение, идентичное нулю в значении внешнего соединения. Это исключение из проблемы конечно.
источник
В статье Википедии по SQL Null есть несколько интересных замечаний о значении NULL, и в качестве независимого от базы данных ответа, если вы знаете о потенциальных последствиях использования значений NULL для вашей конкретной RDBMS, они приемлемы в вашем проекте. Если бы они не были, вы не сможете указать столбцы как обнуляемые.
Просто знайте, как ваша СУБД обрабатывает их в операциях SELECT, таких как математика, а также в индексах.
источник
Вау, правильный ответ «Не допускайте значений NULL, если это не нужно, потому что они ухудшают производительность», так или иначе, является последним оцененным ответом. Я буду высказывать это и уточнять. Когда СУБД допускает значения NULL для не разреженного столбца, этот столбец добавляется в растровое изображение, которое отслеживает, является ли значение NULL для каждой отдельной строки. Таким образом, добавляя возможность NULL к столбцу в таблице, где все столбцы не допускают значения NULL, вы увеличиваете объем памяти, необходимый для сохранения таблицы. Кроме того, вы требуете от СУБД чтения и записи в растровое изображение, что снижает производительность всех операций.
Кроме того, в ряде случаев разрешение NULL будет нарушать 3NF. Хотя я не сторонник 3NF, как многие мои коллеги, рассмотрим следующий сценарий:
В таблице Person есть столбец с именем DateOfDeath, который можно обнулять. Если человек умер, он будет заполнен их DateOfDeath, в противном случае он будет пустым. Существует также необнуляемый битовый столбец, называемый IsAlive. Этот столбец имеет значение 1, если человек жив, и 0, если человек мертв. Подавляющее большинство хранимых процедур использует столбец IsAlive, они заботятся только о том, жив ли человек, а не о его DateOfDeath.
Однако столбец IsAlive нарушает нормализацию базы данных, поскольку он полностью выводится из DateOfDeath. Но поскольку IsAlive встроен в большинство SP, простое решение состоит в том, чтобы сделать DateOfDeath ненулевым и назначить значение по умолчанию для столбца в случае, если человек все еще жив. Несколько SP, использующих DateOfDeath, могут быть затем переписаны для проверки столбца IsAlive и только для DateOfDeath соблюдаются, если человек не жив. Опять же, поскольку большинство сервис-провайдеров заботятся только об IsAlive (немного), а не о DateOfDeath (дата), использование этого шаблона значительно ускоряет доступ.
Полезный сценарий T-SQL для поиска пустых столбцов без NULL во всех схемах:
Если вы запустите это на копии вашей производственной базы данных, вы можете найти разработчики столбцов, помеченные как допускающие значения NULL, которые на практике не имеют значений NULL. Подавляющее большинство из них может быть помечено как NOT NULL, что повышает производительность и уменьшает пространство для хранения.
Возможно, не удастся исключить все NULL во всех таблицах, и при этом все еще будет иметь чистый дизайн, но есть существенное преимущество в устранении как можно большего числа NULL. Оптимизатор работает намного быстрее с этой информацией, и если вы можете исключить все NULL в таблице, вы можете восстановить значительный объем памяти.
Я знаю, что производительность - это не то, о чем администраторы баз данных думают слишком много, но вы можете использовать только ограниченное количество памяти и процессорной мощности для решения, и вам нужно подумать о логическом и физическом дизайне. ,
Также обратите внимание, что это только для настоящих СУБД, и я основываю техническую часть своих ответов на SQL Server. Перечисленный T-SQL для поиска пустых столбцов без нулей также взят из SQL Server.
источник