1. 程式人生 > >sqlserver 大欄位儲存格式(一)

sqlserver 大欄位儲存格式(一)

資料頁

資料頁是包含已經被新增到某個資料庫表中的使用者資料的結構,SQLServer3種資料頁面,每個頁面都以一種不同的格式儲存資料。分別是用於行內資料、行溢位資料和LOB資料的頁面。

和其他型別的頁面一樣,資料頁面具有8KB的固定長度,它們主要由3個主要部分組成,頁首、資料行和行偏移陣列

  1. 頁首

每個資料頁前96個位元組是頁首。

  1. 行內資料的資料行

頁首下面是表的真實資料行的儲存區域。單個數據行的最大容量是8060位元組的行內資料。行也可能有行溢位和儲存在獨立頁上的lob資料。

  1. 行偏移陣列

行偏移陣列是一塊2位元組的條目,其中每個目錄都是表示相應資料行起始頁的偏移量。每一行在這個陣列中都有一個2位元組條目。

行溢位資料:

超出8060位元組大小限制的一種儲存方式是使用變長列,因為對於變長資料來說,SQLServer可以在特殊的行溢位頁中儲存這些列,只要所有長度固定的列適合標準行內大小的限制。可以存在overflow頁上的資料型別包括varbinaryvarcharnvarcharsqlvariant列。

  1. 建立最大定義長度大於8060位元組的一張表:

create table dbo.bigrows

(a varchar(3000),

 b varchar(3000),

 c varchar(3000),

 d varchar(3000)

);

  1. 然後插入一條資料:

insert into bigrows selectreplicate('e',2100),

replicate('f',2100),replicate('g',2100),

replicate('h',2100);

  1. 用下列語句檢視頁面分佈情況:

select object_name(object_id) as name,

partition_id, partition_number aspnum, rows,

allocation_unit_id as au_id, type_descas page_type_desc,

total_pages as pages

from sys.partitions p joinsys.allocation_units a

on p.partition_id = a.container_id

whereobject_id=OBJECT_ID('dbo.bigrows')

結果:有兩頁用於儲存標準行內資料的一行,兩頁用於儲存行溢位資料的一行

  1. 然後用DBCC IND檢視頁面情況:

dbcc ind (Simple, bigrows, -1)

pagetype:

--1資料頁

--2索引頁

--3 LOB或行溢位頁, text_mixed

--4 LOB或行溢位,text_data

--8 GAM page

--9 sgam page

--10 IAM頁面

--11 pfs page

  1. 然後用DBCCPAGE檢視2189頁上面的資料,使用dbccPAGE前必須先執行:

DBCC TRACEON (3604);

dbcc page ('Simple',1,2189,3)

前面的一些內容就不看了,看一下這一頁上面儲存的資料內容(中間...省略了重複內容)

0000000000000000:   3000040004000004 0045085d 889110c5 18656565 0........E.].....eee

0000000000000014:   6565656565656565 65656565 65656565 65656565 eeeeeeeeeeeeeeeeeeee

                        ...      ...

0000000000000820:   6565656565656565 65656565 65656565 65656565 eeeeeeeeeeeeeeeeeeee

0000000000000834:   6565656565656565 65656565 65656565 65020000 eeeeeeeeeeeeeeeee...

0000000000000848:   0001000000471500 00340800 009f0800 00010000  .....G...4..........

000000000000085C:   0067676767676767 67676767 67676767 67676767  .ggggggggggggggggggg

0000000000000870:   6767676767676767 67676767 67676767 67676767 gggggggggggggggggggg

                         ...      ...
0000000000001068:   67676767 6767676767676767 67676767 67676767 gggggggggggggggggggg

000000000000107C:   6767676767676767 67676767 67676767 67676767 gggggggggggggggggggg

0000000000001090:  67686868 68686868 68686868 68686868 68686868  ghhhhhhhhhhhhhhhhhhh

                        ...      ...

0000000000001874:   6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh

0000000000001888:   6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh

000000000000189C:   6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh

00000000000018B0:   6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh

00000000000018C4:   68                                           h     

這一頁上面儲存了我們前面插入的一行資料,可以看到a,c,d列都在這裡面直接儲存的,而b列卻找不到;b列就是我們這邊要找的overflow列,上面結果中紅色部分是24個位元組的overflow指標,結構如下:

  1. 下面是fn_dblog顯示的這個事務的結果,其中第5條的[RowLog Contents 0]記錄了上面一頁的資訊:

0x30000400040000040045085D889110C51865…6565020000000100000047150000340800009F0800000100000067676767…7676868686868…68

可以看到中間也是包含24位元組指標