4. SQL Server Storage Structures (SQL Server存儲結構)

 

2009-05-04

SQL Server Storage Structures (SQL Server存儲結構)

 

4.9 Units of storage(存儲單位) (Page 102)

 

一個數據庫是邏輯分頁(logical pages)的集合,每個分頁的大小是8KB,這個大小是固定的不能被調整。分頁是數據庫的基本存儲單位,也是I/O與鎖定(Locking)的一種單位(I/OLocking還有其它的單位)

 

表與索引由數據庫頁(database page)組成,數據庫頁以段(extent)的方式分配給表和索引。

 

一個段由8個分頁組成(64KB)SQL Server的段有兩種類型:制式的段(uniform extent)與混合的段(mixed extent)。一個制式的段隻能分配給一個數據庫對象,而一個混合的段則可給最多分配給8個數據庫對象,即一個頁可以也隻可以分配給一個數據庫對象。

 

SQL Sever使用混合段的原因是避免一次性分配一個段給一個過小的表。當某個表已被分配了8個分頁並且需要更多的空間時,制式的段將會分配給它。

 

使用系統存儲過程sp_spaceused可以查看某個表空間分配與使用狀況。既使某個表沒有創建索引,sp_spaceusedindex_size欄位依然會返回8KB的索用佔用空間,這是因為SQL Server的每個表都會被分配一個分頁用來存儲一個叫做IAM(Index Allocation Map)的結構。

 

 

 

4.10 Database Pages(數據庫分頁)

 

1.分頁內部結構

用來儲存資料行(table rows)的分頁叫做數據頁(data page),存儲索引信息的分頁叫做索引頁(index page);如果一個表還包含TEXT或者IMAGE的數據類型,那麼這種欄位將會存儲在TEXT頁或者IMAGE頁中;其它的分頁類型有Global Allocation Map(GAM) Page Free Space(PFS)以及Index Allocation Map(IAM)

 

一個數據頁(data page)的內部結構如下圖所示(Figure 4.16)。每個數據頁都包含一個固定的96 byte的數據頁頭(page header),數據頁頭包含的信息有:頁號(page number),指向它的前頁與後頁的指針(如果有的話),以及該數據頁所屬於的對象ID(object ID)(: 對象ID即是數據頁所屬的文件ID)

 

4. SQL Server Storage Structures (SQL Server存儲結構)_第1张图片

 

2009-05-05

除了每個數據行,數據頁上還有一個叫做行偏移量表(row offset table)的結構。行偏移量表由大小為2個字節的項目組成。每個項目記錄一個資料行的行號(row number)以及該資料行的偏移量字節地址(offset byte address)。行偏移量表的第一行的字節偏移量(byte offset)96,這是大小為96KB的頁頭。第二行是116,這是假設資料行的大小為20 byte,則20+96=116,第三行為136,就是96+20+20得來。行偏移量表基本上提供了一個定位資料行的間接方式。這個非常重要,因為非聚集索引可能在它們的葉級索引頁中包含指向資料行的指針。這樣的指針叫做行ID(Row ID),由文件ID(File ID),數據庫分頁號(Database page number)以及 行號(row number)組成。在圖4.16中,最靠近頁頭的行ID由分頁號23行號0組成。

 

由於行ID以這樣的方式構成,所以,當新增或刪除引起資料行在表中的位置改變時,該資料行的行ID無需變更,唯一需要變更的是行偏移量表對應項目的偏移量地址。

 

 

2.資料行內部結構

一個資料行不僅包含資料行資料,還包括一些其它的資訊。這取決於該資料行是否包含可變長度的欄位(variable-length columns),還是僅包含固定長度欄位(fixed-length columns)

 

Figure 4.17

A row containing only fixed length columns

 

4. SQL Server Storage Structures (SQL Server存儲結構)_第2张图片

 

4.17表示了一個僅包含固定長度欄位的資料行結構。該資料行有五個欄位(圖中白色部分),前三個欄位為integer數據類型,第四個欄位為money數據類型,第五個欄位為char(400).

 

資料行內部結構的前二個字節(圖中前兩個灰色部分)為狀態標識。第一個字節告訴SQL Server是否該資料行是primary data row還是forwarded row。此外,它還會指出該資料行是否包含可變長度的欄位。(書本原文 (page106)The first two bytes are used for status bits. The first status byte holds information that tells SQL Server, for example, whether the row is a primary data row or a forwarded row. A status bit in this byte also specifies whether there is variable-length data in the row. In our example there are no variable-length data.)

 

接下來的兩個字節存儲資料行的長度。這個長度是資料行所存儲的數據長度,加上狀態標識的字節長度以及這些字節本身的長度。

 

最後的兩個部分,第一個佔2個字節,它存儲了表示該行欄位數量的信息,最後一個長度不固定,它存儲了一個為空的位圖(bitmap)

 

該資料行所存儲的數據總長度為4+4+4+8+400=420個字節,但實際上它是424個字節------因為還需要加上前面表示狀態的兩個字節和表示長度的兩個字節。

 

如果將上表的第五個欄位的數據類型改為varchar(400)類型,那麼這個資料行內部結構就會是如圖4.18所示。

Figure 4.18

A row containing fixed length and variable length columns

 4. SQL Server Storage Structures (SQL Server存儲結構)_第3张图片

 

在這種包含可變長度欄位的資料行結構中,固定長度的欄位與可變長度的欄位是分開存放的(現在vharchar(400)的欄位放在了最後的位置)。相比僅含固定長度欄位的資料行結構相比,也多出了一些額外資訊。首先,第一個狀態字節將會有一個bit set指出該資料行包含可變長度欄位;其次,圖中第十個部分(NULL Bitmap後面),長度為2個字節,它指出該資料行有多少個可變長度的欄位;緊接著的部分保存的東東,叫做欄位偏移量數組(column offset array),存儲每個可變長度欄位的信息,以便於SQL Server找到這些可變長度欄位的位置。它的每個元素長度均為2個字節。

 

一般情況下,TEXTIMAGE類型的數據不保存在資料行結構裡。

 

 

 

4.11 Looking into database pages(深入了解數據庫分頁)

 

可以使用DBCC PAGE指令查看數據庫分頁的相關信息,語法如下:

1.      DBCC PAGE (dbid | dbname, file id, page number) 顯示頁頭信息

2.      DBCC PAGE (dbid | dbname, file id, page number, 1) 顯示資料行以及行偏移量表信息

 

要得到要查詢的頁號(page number),先用如下語句查詢指定表的第一個page ID(File ID+ page number)

SELECT

first, --第一個page ID

root, --最後一個page ID(如果不是聚集索引的話)

indid –-(0表示沒有聚集索引,1表示有聚集索引)

FROM SYSINDEXES

WHERE ID=OBJECT_ID(‘DBO.FACTORY’) AND INDID IN (0,1)

 

fisrt返回的值如下,為十六進制格式:0x240000000100.

現在來轉換:

Step 1: 去掉0x標識符號,將這些值分別分成1個字節的值:

24 00 00 00 01 00

 

Step 2: 將這些字節反轉過來:

00 01 00 00 00 24

前兩個字節代表File ID,後四個字節代表page number.

因此得到,File ID1page number36.

 

現在執行指令查看頁頭的相關信息:

DBCC TRACEON (3604) –-打開追蹤旗標

 

DBCC PAGE (‘material’,1,36) –查看頁頭

返回如下信息:

 4. SQL Server Storage Structures (SQL Server存儲結構)_第4张图片

 

 

說明:

m_pageId = (1:36) 表示這是在File ID1上的36頁;

m_objID表示這個分頁所屬的對象ID;如果SQL Server的出錯信息中包含分頁號(page number)時,對象ID將非常有用;

如果這個分頁是索引頁的話,那麼m_level表示這個分頁所在的索引層級,m_indexID則表示這個分頁所屬的索引ID;

M_freeData表示這個分頁上的空閒空間超始偏移量; pminlen表示一個資料行的最小值;

M_slotCnt表示行偏移量表上有多少條項目。

 

DBCC PAGE (‘material’,1,36,1) –查看頁頭

 

 

 

4.12 Pages for space management(用於空間管理的分頁)

 

SQL Server中用於空間管理的分頁有如下幾種:

l           Global Allocation Map (GAM) pages

GAM頁記錄當前已經分配了的段信息。一個GAM頁可以管理64000個段。

 

l           Secondary Global Allocation Map (SGAM) pages

SGAM頁記錄已被分配但至少還有一個分頁沒有被分配的混合段的信息。一個SGAM頁同樣可以管理64000個段。

 

l           Index Allocation Map (IAM) pages

IAM頁管理SQL Server中的段分配給表還是索引。一個表或者索引至少有一個IAM頁。如果表或者索引跨越多個文件,則每個文件都會分配一個IAM頁。一個IAM頁可以管理512000個分頁。同一個文件或者索引的IAM頁是鏈接在一起的。

 

l           Page Free Space (PFS) spaces

PFS頁記錄一個單獨的頁是否被分配給一個表, 索引或者其它結構。PFS頁還記錄每個已分配的頁的空間使用狀況。當為一個表或索引尋找空間時,PFS頁會被查詢被分配給這個表或索引的段中的哪個頁有足夠的空間。

 

你可能感兴趣的:(SQL,Server存储引擎)