Нічого собі, правильна відповідь "Не дозволяйте NULL, коли вам не доведеться, бо вони погіршують продуктивність" - якимось чином останньою оцінкою. Я буду його схвалювати і деталізувати. Коли RDBMS дозволяє NULL для нерозрідженого стовпця, цей стовпець додається до растрової карти, яка відстежує, чи є значення NULL для кожного окремого рядка. Отже, додаючи NULL-здатність до стовпця в таблиці, де всі стовпці не дозволяють NULL, ви збільшуєте місце для зберігання, необхідне для збереження таблиці. Крім того, ви вимагаєте від RDBMS для читання та запису до растрової карти, що погіршує продуктивність усіх операцій.
Крім того, у ряді випадків, дозволяючи NULL, це порушить 3NF. Хоча я не є стикером для 3NF, як багато моїх колег, врахуйте наступний сценарій:
У таблиці Person є стовпець під назвою DateOfDeath, який є нульовим. Якщо людина померла, вона заповнюється її DateOfDeath, інакше вона залишиться NULL. Також є ненульовий бітовий стовпець під назвою IsAlive. У цьому стовпці встановлено 1, якщо людина жива, і 0, якщо людина померла. Переважна більшість збережених процедур використовує стовпчик IsAlive, вони дбають лише про те, чи жива людина, а не їх DateOfDeath.
Однак стовпчик IsAlive порушує нормалізацію бази даних, оскільки вона повністю виведена з DateOfDeath. Але оскільки IsAlive є провідним для більшості SP, то прямим рішенням є зробити DateOfDeath ненульовим і призначити значення стовпця за замовчуванням у випадку, якщо людина ще жива. Після цього кілька SP, які використовують DateOfDeath, можуть бути переписані для перевірки стовпця IsAlive і лише вшановувати DateOfDeath, якщо людина не живе. Знову ж таки, оскільки більшість SP не піклуються лише про 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 в таблиці, ви зможете повернути значну кількість місця для зберігання.
Я знаю, що продуктивність - це не те, про що так багато думають DBA, але ви можете кинути на рішення лише обмежену кількість пам’яті та потужність процесора, якийсь момент вам доведеться починати думати про логічний та фізичний дизайн .
Також зауважте, що це стосується лише справжніх RDBMS, і я базую технічну частину своїх відповідей на SQL Server. Перелічений T-SQL для пошуку зведених стовпців без нулів також є від SQL Server.