4. SQL SERVER存儲引擎之數據篇
(4.1)文件
(0)主數據文件.mdf初始文件大小至少為3MB,次要數據文件.ndf初始大小,同日志文件一樣至少為512KB;
(1)SQL SERVER在邏輯上用文件組將文件分批管理(類似ORACLE的TABLESPACE),一個文件組可以包含多個文件,插入數據時,同一個文件組內的所有文件等比例增長。例如:文件組中有兩個文件,初始大小分別為100M和200M,此時插入3M的數據,file1新增(100/300)*3M=1M,file2新增(200/300)*3M=2M。
(2)頁(page),SQL SERVER中的數據文件由8K大小的數據頁組成,每個數據文件中的頁從0開始編號,頁大小不可以自定義,且每個頁只屬於一個數據對象。
(3)區(extent),或者叫擴展,8個物理上連續的頁為一個擴展,即64k;擴展的存在是為了避免不停的分配8k的頁面,提高頁面分配的效率。SQL SERVER有兩種類型的區,如下圖:
混合區:為了節約空間,將少量數據的表或索引存放在混合區,當表或索引的數據增長到8頁時,再使用統一區來存放,一個混合區有8個頁,每個頁可以屬於不同的數據對象,即每個混合區最多為8個數據對象共享。
統一區:由單個數據對象所有,如果對表中現有數據創建索引,且索引的大小超過8頁,則索引將全部使用統一區,沒有混合區的分配過程。
(4.2)頁
(4.2.1)非數據頁
(0)文件頭,每個數據文件的第一頁,頁號為0,該頁主要包括當前文件的屬性描述,比如:文件組ID、文件ID、文件當前大小、文件最大/最小值、文件增量、一系列的LSN等;
(1)頁面空閑空間(PFS),每個數據文件的第二頁,頁號為1,該頁記錄當前數據文件每個數據頁的空間狀態:該頁是為空、已滿1%到50%、已滿51%到80%、已滿81%到95%,還是已滿96%到100%。PFS頁內用1個字節來描述1個數據頁的分配及空間狀態,每個PFS頁約有可用空間8088個字節,即數據文件內約每64M的空間會出現一個PFS頁。
(2)全局分配映射(GAM),每個數據文件的第3頁,頁號為2,該頁記錄當前數據文件每個區的分配狀態,0為已使用(作為混合區或統一區),1為未使用(自由區,未分配)。
(3)共享分配映射(SGAM),每個數據文件的第4頁,頁號為3,該頁記錄當前數據文件哪些區被用作混合區,1為含有自由頁面的混合區,0為自由區或已滿的混合區。
(4)索引分配映射(IAM),該頁跟蹤數據文件中的頁屬於哪個數據對象,IAM頁頭有8個頁面指針,指向數據對象在混合區中的數據頁(如果混合區中的數據被刪除可能少於8個指針),IAM頁內比特位為1表示該區屬於自己所屬的數據對象,比特位為0表示該區不屬於自己所屬的數據對象。
(4.1)每個數據對象的每個分配單元擁有一個IAM頁,IAM同GAM、SGAM一樣可以管理約4G的空間,如果分配單元包含多個文件,或者文件大小超過4G,則需要另外的IAM頁來管理,IAM頁間通過雙向鏈表連接;
(4.2)可以通過sysindexes或sys.system_internals_allocation_units系統目錄得到first_IAM頁面的位置,IAM頁在數據文件中的位置是隨機的,可能IAM頁所在文件並不是所管理的那個文件;
(5)差異更改映射(DCM),每個數據文件的第7頁,頁號為6(頁號4,5為保留頁),該頁跟蹤當前數據文件中,自上次全備份后被修改的區,以提高差異備份的效率,1為被修改過,0為未被修改;
(6)大批量更改映射(BCM),每個數據文件的第8頁,頁號為7,該頁跟蹤當前數據文件中,自上次日志備份后被大批量操作修改的區,1為被修改過,0為未被修改;
(4.2.2)數據頁
(0)數據頁包含頁頭、數據行、行偏移矩陣三部分,如下圖:
(1)行內數據(IN_ROW_DATA),單行未超過8060B的數據行,或者單行超過8060B但仍存儲在當前頁的數據,稱為行內數據;
(2)行溢出數據(ROW_OVERFLOW_DATA),在SQL SERVER2005及以后的版本中,如果表中定義了變成的數據類型,允許單行數據長度突破8060B,超過的部分即為行溢出數據,如果變長列被更新后縮短,可能會被移回行內數據頁(通常減少1000字節以上時,SQL SERVER才會有檢查是否可移回)。
(3)大對象數據(LOB_DATA),存放如text/image/xml/varchar(max)等最大長度可超過8000B的數據類型的數據;
大對象數據也是通過8k的數據頁來存放數據,在行內數據頁中包含一個16字節的指針指向大對象數據的根頁,大對象數據通過B-樹結構來組織多個數據頁;
可以通過打開text in row選項將大對象數據存儲在行內數據頁,當大對象數據被更新超過500B時,則會從行內數據頁將大對象數據移出,這是個日志操作,因此移動操作比較耗時,所以不建議開啟該選項;
(4)數據行
每個數據行,除了每個列的數據之外,還包括狀態位、定長列偏移量、總列數、NULL位圖、變長列數、列偏移矩陣,這些即為行開銷。
創建全定長列的表,數據行如下圖:
if object_id ('test_col') is not null
drop table test_col;
GO
create table test_col
(
col1 char(1),
col2 char(2)
)
GO
insert into test_col values('A','B')
--------------------------------------------------------------------------------------
原文轉自:http://qianzhang.blog.51cto.com/317608/1217346
--------------------------------------------------------------------------------------