SQL Server 解析行溢出數(shù)據(jù)的存儲(chǔ)

字號(hào):


    SQL Server2000中最大數(shù)據(jù)行的大小為8060(我們可以使用的大小為8039),即創(chuàng)建表時(shí)所有列的大小總和不能超過8060。在2005中,對(duì)于定長(zhǎng)的數(shù)據(jù),依然保留了這個(gè)限制(不過在2005中,我們可以使用的大小為8053,而不是8039)。那么在SQL SERVER2005中對(duì)于一行是不是只能存儲(chǔ)最多8053字節(jié)的數(shù)據(jù)呢?能不能突破8060的這個(gè)限制呢?
    在SQL SERVER2000中沒有辦法,但是在SQL SERVER2005中,是有可能的。在SQL SERVER2005使用變長(zhǎng)數(shù)據(jù),可以突破8060的限制。因?yàn)镾QL SERVER2005中對(duì)數(shù)據(jù)每行記錄的限制做了一定的調(diào)整,對(duì)于包含變長(zhǎng)類型的表,每一列的長(zhǎng)度仍然必須在每行8000以內(nèi),但是它們的合并寬度可以超過8060B的限制。
    在SQL SERVER2005中,可以把變長(zhǎng)列存儲(chǔ)在行溢出頁面。當(dāng)一個(gè)列需要從一個(gè)常規(guī)頁面轉(zhuǎn)移到一個(gè)行溢出頁面時(shí),SQL 2005會(huì)保留一個(gè)包含行溢出信息的指針作為原始記錄的一部分,指針的大小為24B,并且對(duì)于每個(gè)變長(zhǎng)列,無論該列是否存儲(chǔ)在記錄中,記錄還需要2個(gè)字節(jié)。
    【測(cè)試】
    create table tb(col char(7000),col2 varchar(3000),col3 varchar(3000))
    go
    insert into tb
    values('aaa',replicate('bbb',1000),replicate('ccc',1000))
    go
    dbcc ind(test,tb,-1) -–得到的頁面號(hào)為89,80,6321,6315.其中89,6321為IAM頁,80與6315為數(shù)據(jù)頁
    dbcc traceon(3604)
    dbcc page(test,1,89,1)
    dbcc page(test,1,80,1)
    dbcc page(test,1,6321,1)
    dbcc page(test,1,6315,1)
    下面分別解析所生成的IAM頁與數(shù)據(jù)頁,就可以看到行溢出數(shù)據(jù)在SQL SERVER2005中是如何來進(jìn)行存儲(chǔ)的。
    一、解析IAM頁
    因?yàn)?9與6321頁面結(jié)構(gòu)是相同的,解析其中的第一即可,以89頁為例。
    dbcc traceon(3604)
    dbcc page(test,1,89,1)
    得到的結(jié)果:
    1、 該頁面總共兩行
    2、 第一行記錄了該IAM記錄的數(shù)據(jù)頁(后面的注釋說明了該數(shù)據(jù)的作用)
    00000000: 00005e00 00000000 00000000 00000000 †--該行的長(zhǎng)度
    00000010: 00000000 00000000 00000000 00000000 †...............
    00000020: 00000000 00000000 00000000 01005000 †--負(fù)責(zé)的數(shù)據(jù)頁面id
    00000030: 00000100 00000000 00000000 00000000 †...............
    二、解析數(shù)據(jù)頁
    1、 解析80頁面數(shù)據(jù):
    00000000: 30005c1b 61616120 20202020 20202020 –-前四個(gè)字節(jié)就不解釋了
    ……
    00001B50: 20202020 20202020 20202020 0300f802
    -–0300總共有三列,f8 null位圖,0200變長(zhǎng)列有兩列
    00001B60: 007d9b95 9b020000 65010000 00f65c00
    --雖然第二列和第三列的數(shù)據(jù)存儲(chǔ)在另外的數(shù)據(jù)頁,但每個(gè)列依然會(huì)占用兩個(gè)字節(jié)。
    00001B70: 00b80b00 00ab1800 00010000 00020000
    00001B80: 65010000 00c04700 00b80b00 00ab1800
    00001B90: 00010001 00
    020000 65010000 00f65c00 00b80b00 00ab1800 00010000 00
    第一個(gè)行溢出的指針
    020000 65010000 00c04700 00b80b00 00ab1800 00010001 00
    第二個(gè)行溢出的指針
    一個(gè)長(zhǎng)度為24字節(jié)的指針。24字節(jié)包含的部分分別如下:
    0200
    00
    65
    01000000
    f65c0000
    B80b0000
    ab180000
    0100
    0000
    溢出列類型
    在B-樹種的層次
    暫時(shí)不用,無實(shí)際意義
    Lob數(shù)據(jù)更新的次數(shù)
    用于dbcc checktable使用的一個(gè)隨機(jī)值,在lob存在的周期中不會(huì)改變
    該列的長(zhǎng)度。
    (計(jì)算時(shí)為00000bb8)
    該部分?jǐn)?shù)據(jù)所在的頁面號(hào)
    該部分?jǐn)?shù)據(jù)所在的文件號(hào)
    該部分?jǐn)?shù)據(jù)所在