Вау, правильный ответ «Не допускайте значений 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 во всех схемах:
select 'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' WHERE ' + QUOTENAME(c.name) + ' IS NULL)
AND (SELECT COUNT(*) FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ') > 1 PRINT ''' + s.name + '.' + t.name + '.' + REPLACE(c.name, '''', '''''') + ''''
from sys.columns c
inner join sys.tables t ON c.object_id = t.object_id
inner join sys.schemas s ON s.schema_id = t.schema_id
where c.is_nullable = 1 AND c.is_computed = 0
order by s.name, t.name, c.name;
Если вы запустите это на копии вашей производственной базы данных, вы можете найти разработчики столбцов, помеченные как допускающие значения NULL, которые на практике не имеют значений NULL. Подавляющее большинство из них может быть помечено как NOT NULL, что повышает производительность и уменьшает пространство для хранения.
Возможно, не удастся исключить все NULL во всех таблицах, и при этом все еще будет иметь чистый дизайн, но есть существенное преимущество в устранении как можно большего числа NULL. Оптимизатор работает намного быстрее с этой информацией, и если вы можете исключить все NULL в таблице, вы можете восстановить значительный объем памяти.
Я знаю, что производительность - это не то, о чем администраторы баз данных думают слишком много, но вы можете использовать только ограниченное количество памяти и процессорной мощности для решения, и вам нужно подумать о логическом и физическом дизайне. ,
Также обратите внимание, что это только для настоящих СУБД, и я основываю техническую часть своих ответов на SQL Server. Перечисленный T-SQL для поиска пустых столбцов без нулей также взят из SQL Server.