Скільки значення "Null" приймає у SQL Server


118

У мене є велика таблиця з кажуть 10 колонок. 4 з них залишаються недійсними більшість разів. У мене є запит, що нульове значення приймає будь-який розмір або розмір у байтах. Я прочитав кілька статей, деякі з них говорять:

http://www.sql-server-citation.com/2009/12/common-mistakes-in-sql-server-part-4.html

Існує помилкова думка, що якщо в таблиці є значення NULL, воно не займає місця для зберігання. Справа в тому, що значення NULL займає простір - 2 байти

SQL: Використання значень NULL та значень за замовчуванням

NULLЗначення в базах даних є значення , система , яка займає один байт пам'яті , і вказує на те, що значення не присутній на відміну від простору або нуль або будь-яке інше значення по замовчуванню.

Чи можете ви, будь ласка, вказувати мене щодо розміру, взятого за нульовим значенням.

Відповіді:


146

Якщо поле фіксовано по ширині, зберігання NULL займає таке ж простір, як і будь-яке інше значення - ширина поля.

Якщо поле змінної ширини, значення NULL не займає місця.

На додаток до місця, необхідного для зберігання нульового значення, є також накладні витрати на наявність нульового стовпчика. Для кожного рядка по одному біту стовпця використовується один біт для позначення того, чи є значення для цього стовпця нульовим чи ні. Це вірно, незалежно від того, чи стовпець є фіксованою або змінною довжиною.


Причина розбіжностей, які ви помітили в інформації з інших джерел:

  • Початок першої статті трохи вводить в оману. У статті йдеться не про витрати на збереження значення NULL, а про витрати на можливість зберігання NULL (тобто про витрати на створення стовпця, що зводиться до нуля). Це правда, що витрачається щось на простір пам’яті, щоб зробити стовпчик нульовим, але після того, як ви зробите це, потрібно менше місця для зберігання NULL, ніж потрібно для зберігання значення (для стовпців змінної ширини).

  • Другим посиланням, здається, є питання про Microsoft Access. Я не знаю деталей, як Access зберігає NULL, але я не здивуюсь, якщо він відрізняється від SQL Server.


1
@Mark "Це правда, що витрачається щось на простір для зберігання стовпця, який є нульовим, але після того, як ви зробите це, що потрібно менше місця для зберігання NULL, ніж потрібно для зберігання значення (для стовпців зі змінною шириною)" Цим ви маєте на увазі скажімо, що це займає 1 біт як розмір, взятий в пам'яті для змінних типів даних.
Rocky Singh

13
Найменша адресна пам'ять у більшості комп'ютерних систем - одна byte(як правило, 8 біт). Тож насправді, bitа byte. Відмінна відповідь: +1.
JohnB

20
Однак і другий біт, і третій біт, і аж до восьмого біта вміщуються в один байт.
Матті Вірккунен

1
@Mark - Так, це виглядає набагато чіткіше. Вибачте за коментар, що зникає. Я мав намір переглянути його, але моє підключення до Інтернету пішло між видаленням та поданням! Це також трохи залежить (від розділу коментарів тут) "Для купи та кластеризованих індексів завжди є растрова NULL. Для некластеризованих індексів не буде, якщо всі стовпці в індексі НЕ NULL."
Мартін Сміт

2
@Martin Smith: Я цього не знав. Це ускладнює все, тому що якщо я правильно його розумію, це означає, що створення стовпця, який є нульовим, не збільшує необхідний простір для зберігання (оскільки нульова растрова карта завжди присутня), якщо цей стовпець також не знаходиться в індексі та інші стовпці в індексі не зведені до нуля. У цьому випадку індекс тепер повинен містити нульову растрову карту.
Марк Байєрс

30

Наступні твердження , що посилання , якщо поле є змінною довжиною, тобто varcharпотім NULLприймає 0 байт (плюс 1 байти використовуються для прапора , чи є значення NULLчи ні):

Наведене вище посилання, а також посилання нижче стверджують, що для стовпців із фіксованою довжиною, тобто char(10)або int, значення NULLзаймає довжину стовпця (плюс 1 байт, щоб позначити, чи це), NULLчи ні:

Приклади:

  1. Якщо встановити char(10)значення " NULL," він займає 10 байтів (нуль)
  2. А intзаймає 4 байти (також нульове).
  3. varchar(1 million)Набір для NULLзаймає 0 байт (+ 2 байта)

Примітка: за незначною дотичною величиною зберігання varcharє довжина введених даних + 2 байти.


Не хочете, щоб варчар, що зберігає NULL, взяв 0 + 2 + 1 (накладні NULL) байти?
Акаш

Щоб позначити NULL, це має бути + 1 біт . @Akash: 2 байти не повинні бути необхідними, оскільки растрова карта вже позначає значення як NULL (інформація не буде додана).
Сімо Ківісто

5

За цим посиланням :

Кожен рядок має нульову растрову карту для стовпців, які дозволяють нулю. Якщо рядок у цьому стовпці є нульовим, то біт у растровій мапі дорівнює 1, це 0.

Для типів даних змінного розміру фактичний розмір становить 0 байт.

Для типу даних фіксованого розміру фактичний розмір є типовим розміром типу даних у байтах, встановлених за замовчуванням (0 для чисел, '' для знаків).


Ви маєте на увазі сказати для таких типів даних, як nvarchar (max) varchar (max) Null займе 0 байтів, а для int, символів тощо він прийме розмір за замовчуванням до значень за замовчуванням, які вони мають?
Rocky Singh

4

Збереження значення NULL не займає місця.

"Справа в тому, що значення NULL займає простір - 2 байти."

Це неправильне уявлення - це 2 байти в рядку , і я майже впевнений, що всі рядки використовують ці 2 байти незалежно від того, чи є якісь нульові стовпці.

Значення NULL у базах даних - це системне значення, яке займає один байт сховища

Мова йде про бази даних взагалі, а не конкретно про SQL Server. SQL Server не використовує 1 байт для зберігання значень NULL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.