Ile rozmiaru ma wartość „Null” w programie SQL Server

118

Mam duży stół z powiedzmy 10 kolumnami. 4 z nich przez większość czasu pozostają nieważne. Mam zapytanie, które ma wartość null, która ma dowolny rozmiar lub nie ma rozmiaru w bajtach. Przeczytałem kilka artykułów, o których niektórzy z nich mówią:

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

Istnieje błędne przekonanie, że jeśli mamy wartości NULL w tabeli, nie zajmuje to miejsca w pamięci. Faktem jest, że wartość NULL zajmuje miejsce - 2 bajty

SQL: Używanie wartości NULL w porównaniu z wartościami domyślnymi

NULLWartość w bazach danych jest wartością system, który zajmuje jeden bajt pamięci i wskazuje, że wartość nie jest obecna w przeciwieństwie do przestrzeni lub zero lub jakiejkolwiek innej wartości domyślnej.

Czy możesz mi pomóc w odniesieniu do rozmiaru przyjmowanego przez wartość zerową.

Rocky Singh
źródło

Odpowiedzi:

146

Jeśli pole ma stałą szerokość, zapis NULL zajmuje tyle samo miejsca, co każda inna wartość - szerokość pola.

Jeśli pole ma zmienną szerokość, wartość NULL nie zajmuje miejsca.

Oprócz miejsca wymaganego do przechowywania wartości null istnieje również narzut związany z posiadaniem kolumny dopuszczającej wartość null. Dla każdego wiersza jest używany jeden bit na każdą kolumnę dopuszczającą wartość null, aby zaznaczyć, czy wartość dla tej kolumny ma wartość null, czy nie. Dzieje się tak niezależnie od tego, czy kolumna ma stałą, czy zmienną długość.


Przyczyna rozbieżności, które zauważyłeś w informacjach z innych źródeł:

  • Początek pierwszego artykułu jest nieco mylący. Artykuł nie mówi o koszcie przechowywania wartości NULL, ale o koszcie posiadania możliwości przechowywania wartości NULL (tj. Koszcie uczynienia kolumny dopuszczającą wartość zerową). Prawdą jest, że uczynienie kolumny dopuszczającą wartość null kosztuje trochę miejsca w pamięci, ale kiedy już to zrobisz, przechowywanie wartości NULL zajmuje mniej miejsca niż przechowywanie wartości (dla kolumn o zmiennej szerokości).

  • Drugie łącze wydaje się być pytaniem o Microsoft Access. Nie znam szczegółów, w jaki sposób Access przechowuje wartości NULL, ale nie zdziwiłbym się, gdyby różni się od SQL Server.

Mark Byers
źródło
1
@Mark „Prawdą jest, że nadanie kolumny wartości zerowej kosztuje coś w pamięci, ale kiedy już to zrobisz, przechowywanie wartości NULL zajmuje mniej miejsca niż przechowywanie wartości (w przypadku kolumn o zmiennej szerokości)” Masz na myśli mówiąc, że zajmuje 1 bit jako rozmiar przyjmowany w pamięci dla zmiennych typów danych.
Rocky Singh
13
Najmniejsza adresowalna jednostka pamięci w większości systemów komputerowych to jeden byte(zazwyczaj 8 bitów). Tak więc w rzeczywistości bitplik byte. Świetna odpowiedź Znak: +1.
JohnB
20
Jednak drugi i trzeci bit i aż do ósmego bitu mieszczą się w tym samym bajcie.
Matti Virkkunen
1
@Mark - Tak, wygląda o wiele wyraźniej. Przepraszamy za znikający komentarz. Chciałem to poprawić, ale moje połączenie internetowe zepsuło się między usunięciem a przesłaniem! Zależy to również nieco (z sekcji komentarzy tutaj) „W przypadku rekordu sterty i indeksu klastrowego zawsze istnieje mapa bitowa o wartości NULL. W przypadku indeksów nieklastrowych nie będzie, jeśli wszystkie kolumny w indeksie NIE mają wartości NULL”.
Martin Smith
2
@ Martin Smith: Tego nie wiedziałem. To sprawia, że ​​sprawa jest bardziej skomplikowana, ponieważ jeśli dobrze to rozumiem, oznacza to, że nadanie kolumnie wartości zerowej nie zwiększa wymaganej przestrzeni dyskowej (ponieważ pusta mapa bitowa jest zawsze obecna), chyba że ta kolumna również znajduje się w indeksie, a inne kolumny w indeksie nie podlegają wartości null. W takim przypadku indeks musi teraz zawierać pustą bitmapę.
Mark Byers
30

Poniższy link stwierdza, że ​​jeśli kolumna ma zmienną długość, tj. varcharWtedy NULLzajmuje 0 bajtów (plus 1 bajt jest używany do oznaczenia, czy wartość jest, NULLczy nie):

Powyższy link, jak również poniższy link, twierdzą, że dla kolumn o stałej długości, tj. char(10)Lub int, wartość NULLzajmuje długość kolumny (plus 1 bajt do oznaczenia, czy jest, NULLczy nie):

Przykłady:

  1. Jeśli ustawisz char(10)na NULL, zajmuje 10 bajtów (wyzerowane)
  2. An intzajmuje 4 bajty (również zerowane).
  3. varchar(1 million)Zestaw do NULLzajmuje bajty 0 (+ 2 bajty)

Uwaga: w niewielkim stopniu rozmiar pamięci varcharto długość wprowadzonych danych + 2 bajty.

JohnB
źródło
Czy varchar przechowujący wartość NULL nie zająłby bajtów 0 + 2 + 1 (NULL narzut)?
Akash
Powinien wynosić + 1 bit, aby oznaczyć wartość NULL. @Akash: 2 bajty nie powinny być potrzebne, ponieważ mapa bitowa już oflagowuje wartość jako NULL (żadne informacje nie zostaną dodane).
Simo Kivistö
5

Z tego linku :

Każdy wiersz ma pustą mapę bitową dla kolumn, które dopuszczają wartości null. Jeśli wiersz w tej kolumnie jest pusty, to bit w mapie bitowej ma wartość 1, w przeciwnym razie jest to 0.

Dla typów danych o zmiennej wielkości rzeczywisty rozmiar wynosi 0 bajtów.

Dla typu danych o stałym rozmiarze, rzeczywisty rozmiar jest domyślnym rozmiarem typu danych w bajtach ustawionym na wartość domyślną (0 dla liczb, „” dla znaków).

Kevin LaBranche
źródło
Chcesz powiedzieć, że dla typów danych takich jak nvarchar (max) varchar (max) Null zajmie 0 bajtów, a dla int, chars itp. Przyjmie domyślny rozmiar do wartości domyślnych, które mają?
Rocky Singh
4

Przechowywanie wartości NULL nie zajmuje miejsca.

„Faktem jest, że wartość NULL zajmuje miejsce - 2 bajty”.

To błędne przekonanie - to 2 bajty na wiersz i jestem prawie pewien, że wszystkie wiersze używają tych 2 bajtów, niezależnie od tego, czy są jakieś kolumny dopuszczające wartość null.

Wartość NULL w bazach danych to wartość systemowa zajmująca jeden bajt pamięci

Mówi się ogólnie o bazach danych, a nie konkretnie o SQL Server. SQL Server nie używa 1 bajtu do przechowywania wartości NULL.

Gabe
źródło