天天看點

SQL Server :了解資料記錄結構

資料記錄存儲我們具體的資料,換句話說,它存在堆表裡,或者存在聚集索引的葉子節點。資料記錄結構是為了讓SQL Server更高效的管理資料。我們來看下資料記錄結構示意圖:

SQL Server :了解資料記錄結構

上圖中藍色部分是所有資料記錄部分(即系統行開銷,大小基于列個數,等于或大于7 bytes),綠色部分是表結構裡取決于定長/變長列的資料記錄部分(實際存放的資料,大小基于實際資料)。

用做狀态位1的第1位元組(8位)是用來定義記錄的屬性:

第0位:版本資訊,在SQL Server 2008裡始終是0;

第1-3位:這3位用來定義記錄類型;

0 資料記錄(data record)

1 轉發記錄(Forwarded record)

2 轉發存根(a forwarding stub)

3 索引記錄(Index record)

4 二進制堆碎片或行溢出資料(blob fragment or row overflow data)

5 鬼影索引記錄(ghost index record)

6 鬼影資料記錄(ghost data record)

7 鬼影版本記錄(ghost version record)

第4位:存在空值位圖(Null bitmap )或沒有。在SQL Server 2008裡沒有不為空的列也會有空值位圖(Null bitmap );

第5位:表示是否存在變長列;

第6位:表示該列包含版本資訊;

第7位:在SQL Server裡未使用;

用作狀态位2的第2位元組(8位)。隻有1位用來表示這條記錄是否為鬼影轉發記錄(ghost forwarded record)。

下2個位元組用來存儲行頭開始到定長列結尾長度。它包含2個狀态位,2個位元組用作這個清單示在表中定長資料的實際長度。例如如果表裡沒有定長列,這個列的值會是4。這和頁頭列pminlen顯示的值是一樣的。

下n個位元組用來存儲在表中的定長資料,n就是在表中所有定長列的長度。如果表裡的所有列都是變長列,這一部分就沒有。

下2個位元組用來存儲表裡的列數。

下n個位元組用作空值位圖,每個bit對應一個列,1表示對應列為空。n的值為:列數 / 8,将值取整。

下2個位元組用來存儲表裡變長列個數。

下n個位元組用來存儲每個變長列結束為止的偏移量。每個變長列需要2位元組,n的值為:變長列數 * 2 。

最後n個位元組用來存儲所有變長列值,n的值為所有變長列的實際長度的總長度。

 我們來看一個具體的例子:

建立資料庫,并插入2條記錄

使用DBCC IND指令檢視表對應頁清單:

SQL Server :了解資料記錄結構

我們看到資料頁号為79。

使用DBCC PAGE指令檢視頁資訊:

SQL Server :了解資料記錄結構

在頁頭pminlen的值是221,包括定長列的總長217 bytes(50+50+100+5+4+8),2 bytes用作狀态位(行頭系統開銷),2 byte 用作由行頭開始到定長列結尾長度。

在記錄槽提到的長度224,包括頁頭pminlen的值,1 byte用作空值位圖(6/8 取整為1)和2 bytes 的字段個數。

我們來看一個變長列的表。

建立表并插入資料後,檢視表對應的頁:

SQL Server :了解資料記錄結構

我們看到資料頁号為202。

SQL Server :了解資料記錄結構

pminlen值為30,包含:

1 byte 狀态位1

1 byte 狀态為2

2 bytes 存儲行頭開始到定長列結尾長度

26 bytes 所有定長列總長度(10+3+10+3:tittle,dob,phone,countrycode)

Title  CHAR(10) NOT NULL

dob date NOT NULL

phone CHAR(10)

Countrycode CHAR(3)

可以用下列語句驗證下定長列總長度: 

 在槽0顯示的81長度包含:

phone CHAR(10)  

2 bytes 存儲列個數

2 bytes 用作空值位圖,字段個數/8後取整,即 9/8 得到2

2 bytes 存儲變長列個數

10 bytes 用來存儲每個變長列結束位置的偏移量 變長列個數 * 2,即 5 * 2 得到10,5個變長列包含:

FirstName VARCHAR(100)

Lastname VARCHAR(100)  

email VARCHAR(50)

Designation VARCHAR(100)  

PersonalPreference VARCHAR(100)

35 bytes 用來存儲所有變長列的實際長度,這個可以使用下列語句得到

SQL Server :了解資料記錄結構

總結下每條記錄的系統行開銷:

行頭系統資料(2 bytes)+由行頭開始到定長列結尾長度(2 bytes)+列個數(2 bytes)+空值位圖資料(取整(列個數/8) n bytes)

即 2 bytes + 2 bytes + 2 bytes + 取整(列個數/8)

當列個數小于等于8時,系統行開銷始終是7 bytes,往上沒增加8列,增加1 bytes,即系統系統行開銷始終大于等于7 bytes。

對于在SQL Server裡資料記錄的存儲格式,希望你已經有了清晰的認識。