Spis treści:

Kategoria:SQL Server


Jak określić rozmiar danych w kolumnie SQL

Pobieranie rzeczywistego rozmiaru danych w tabeli

Jeżeli w tabeli mamy już jakieś dane, wtedy do pobrania rozmiaru może posłużyć funkcja wbudowana DATALENGTH. Sposób użycia tej funkcji pokazany jest poniżej:

CREATE TABLE TypeSizes
(
TypeInt int,
TypeDecimal decimal(8,3),
TypeGuid uniqueidentifier,
TypeNVarchar nvarchar(16)
)
INSERT INTO TypeSizes VALUES(5,159.112,NEWID(),'Gupik')
SELECT DATALENGTH(TypeInt),
       DATALENGTH(TypeDecimal),
       DATALENGTH(TypeGuid),
       DATALENGTH(TypeNVarchar)
FROM TypeSizes

Rozmiary typów standardowych

Szacowanie rozmiarów tabel jest jednym z ważniejszych etapów projektowania bazy danych oraz indeksów. Jak wiemy, istnieją typy, które mają pewien stały rozmiar, oraz typy, które mają rozmiar zmienny, w zależności od ilości danych w nim przechowywanych lub precyzji. Na początek przyjrzyjmy się rozmiarom typów o stałym rozmiarze:

Nazwa typuRozmiar (w bajtach)
bigint8
bit1
date3
datetime8
datetime28
datetimeoffset10
float8
image*16
int4
money8
ntext*16
real4
smalldatetime4
smallint2
smallmoney4
text*16
time5
timestamp8
tinyint1
uniqueidentifier16

Szczególną uwagę należy zwrócić na typy oznaczone gwiazdką. Podany przy nich rozmiar to nie jest wszystko. Rozmiar ten dotyczy tylko i wyłącznie miejsca zajmowanego w obszarze stosu lub indeksu klastrowanego. Miejsce zajmowane jest przez odwołanie do innego obszaru (tzw. LOB_DATA, obszar obiektów dużych). Sam obiekt mieści się w innym miejscu i tam zajmuje tyle miejsca, ile rzeczywiście potrzeba. Jak pobrać rozmiar w tym dodatkowym obszarze napiszę nieco później.

Warto też wiedzieć, że od SQL Server 2005 wzwyż nie powinno się już używać takich typów jak ntext, text, image. Mogą być one usunięte w jednej z przyszłych wersji SQL Server, ale powodują powstawanie pewnego narzutu czasowego (i minimalnego narzutu pamięciowego). Zobacz też artykuł: Porównanie ntext i nvarchar(max).

Rozmiary typów decimal i numeric

Trochę inną grupę stanowią typy decimal oraz numeric. Definiując te typy podajemy ilość cyfr znaczących, oraz ilość cyfr po przecinku. Ma to oczywiście wpływ na rozmiar. Zależności przedstawione są w poniższej tabeli:

Ilość cyfr (precyzja)Rozmiar (w bajtach)
1-95
10-199
20-2813
29-3817

Jaki z tego wniosek? Jeżeli nie jesteśmy dokładnie pewni, jaki zakres będą przyjmować wartości, możemy ustalić maksymalną precyzję w ramach tego samego rozmiaru pola.

Rozmiary typów tekstowych

Jeszcze inny sposób liczenia stosuje się w przypadku typów tekstowych. Typy char i nchar mają stały rozmiar, który podawany jest podczas definiowania tabeli. Przyjrzyjmy się następującemu skryptowi:

CREATE TABLE TypeSizes
(
TypeChar char(5),
TypeNChar nchar(5)
)
INSERT INTO TypeSizes VALUES ('BB''CC')
SELECT DATALENGTH(TypeChar), DATALENGTH(TypeNChar) FROM TypeSizes

Jak można się przekonać doświadczalnie (to dla tych, którzy nie wierzą dokumentacji), rozmiar pola jest niezależny od rozmiaru przechowywanych danych. Typ char to zwykłe znaki jednobajtowe, natomiast nchar to znaki przechowywane w postaci UNICODE, czyli dwubajtowe. Stąd wynika różnica: 5 bajtów dla char(5) i 10 bajtów dla nchar(5).

Trochę inaczej jest w przypadku typów varchar i nvarchar. Dopasowują one swój rozmiar do zawartości. Można się o tym przekonać wykonując poniższy skrypt:

CREATE TABLE TypeSizes
(
TypeVarchar varchar(5),
TypeNvarchar nvarchar(5)
)
INSERT INTO TypeSizes VALUES ('BB''CC')
SELECT DATALENGTH(TypeVarchar), DATALENGTH(TypeNvarchar) FROM TypeSizes

W tym przypadku wartość w polu typu varchar(5) zajmuje 2 bajty, natomiast wartość w polu typu nvarchar(5) - 4 bajty.

Inne typy

W SQL Server istnieje jeszcze kilka interesujących typów. Typy nvarchar(MAX) i varchar(MAX) zajmują tyle samo co nvarchar(N) i varchar(N), ale mogą przekraczać rozmiar 8kB. Podobnie jest w przypadku danych binarnych, czyli varbinary(N) i varbinary(MAX). Pole typu xml przechowywane jest tak samo jak nvarchar(MAX).

Kategoria:SQL Server

, 2013-12-20

Brak komentarzy - bądź pierwszy

Dodaj komentarz
Wyślij
Ostatnie komentarze
Dzieki za rozjasnienie zagadnienia upsert. wlasnie sie ucze programowania :).
Co się stanie gdy spróbuję wyszukać:
SELECT * FROM NV_Airport WHERE Code='SVO'
SELECT * FROM V_Airport WHERE Code=N'SVO'
(odwrotnie są te N-ki)
Będzie konwersja czy nie znajdzie żadnego rekordu?