SQLSERVER數(shù)據(jù)庫中數(shù)據(jù)存儲(chǔ):
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比磐安網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式磐安網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋磐安地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴。
一:存儲(chǔ)文件類型
SQLSERVER有兩種數(shù)據(jù)存儲(chǔ)文件,分別是數(shù)據(jù)文件和日志文件。
其中:數(shù)據(jù)文件是以8K(=8192Byte)的頁面(Page)作為存儲(chǔ)單元的。
而日志文件是以日志記錄作為存儲(chǔ)單元。本文只討論數(shù)據(jù)文件的存儲(chǔ)方式,不涉及到日志文件存儲(chǔ)方式。
數(shù)據(jù)文件以頁面做為存儲(chǔ)單元存儲(chǔ)數(shù)據(jù),要理解數(shù)據(jù)文件的存儲(chǔ)方式,必須了解SQLSERVER中定義的頁面類型種類。
二:頁面類型
SQLSERVER中頁面類型有8種,具體每種類型的詳細(xì)說明,見下圖:
用戶的數(shù)據(jù)一般存放在數(shù)據(jù)頁面中,由上圖可以看出,數(shù)據(jù)頁包含數(shù)據(jù)行中除 text、ntext 和 image 數(shù)據(jù)外的所有數(shù)據(jù),text、ntext 和 image 數(shù)據(jù)存儲(chǔ)在單獨(dú)的頁中。那么在一個(gè)數(shù)據(jù)頁面中,數(shù)據(jù)是如何存放,SQLSERVER又是根據(jù)什么來定位頁面與頁面上的數(shù)據(jù)呢。要回答這個(gè)問題,有必要先了解數(shù)據(jù)頁面的具體結(jié)構(gòu)。
三:數(shù)據(jù)頁面結(jié)構(gòu)
在數(shù)據(jù)頁上,數(shù)據(jù)行緊接著頁首按順序放置。在頁尾有一個(gè)行偏移表。在行偏移表中,頁上的每一行都有一個(gè)條目,每個(gè)條目記錄那一行的第一個(gè)字節(jié)與頁首的距離。行偏移表中的條目序列與頁中行的序列相反。數(shù)據(jù)頁面結(jié)構(gòu)如下圖所示,下面將詳細(xì)解釋
其中:數(shù)據(jù)頁面頁首:96個(gè)字節(jié),保存著頁面的系統(tǒng)信息,如頁的類型、頁的可用空間量、擁有頁的對(duì)象的對(duì)象 ID 以及該頁面所屬于哪個(gè)物理文件。
數(shù)據(jù)區(qū):對(duì)應(yīng)于上圖中所有數(shù)據(jù)行的總區(qū)域,存放真正的數(shù)據(jù),是以Slot為單位。一個(gè)Slot就是對(duì)應(yīng)于一條數(shù)據(jù)記錄行,從0開始編號(hào),以16進(jìn)制反序保存,Slot0, Slot1....。
行偏移數(shù)組:用于記錄該數(shù)據(jù)頁面中每個(gè)Slot在數(shù)據(jù)頁面所處的相對(duì)位置,便于定位和檢索每個(gè)Slot在數(shù)據(jù)頁面中的位置,數(shù)組中每個(gè)記錄占兩個(gè)字節(jié)。
四:存儲(chǔ)分配單位:盤區(qū)(擴(kuò)展 Extend)
雖然SQLSERVER中數(shù)據(jù)文件存儲(chǔ)單位是頁面(Page),但實(shí)際SQLSERVE并不是為頁面為單位給數(shù)據(jù)分配空間,SQLSERVER默認(rèn)的存儲(chǔ)分配單位是盤區(qū)。這樣做的主要原因是為了提高性能。為了避免頻繁的讀寫IO,在表或其它對(duì)象分配存儲(chǔ)空間,不是直接分配一個(gè)8K的頁面,而是以一個(gè)盤區(qū)(Extend)為存儲(chǔ)分配單位,一個(gè)盤區(qū)為8個(gè)頁面(=8*8K=64K)。
但是這樣做雖然減少了頻繁的IO讀寫,提高的數(shù)據(jù)庫性能,但卻導(dǎo)致出一個(gè)新問題,那就是在存儲(chǔ)那些只有少量數(shù)據(jù),不足8K的對(duì)象,如果也是分配給一個(gè)盤區(qū),就會(huì)存在存儲(chǔ)空間上的浪費(fèi),降低了空間分配效率。
為解決上述問題,SQLSERVER提供了一種解決方案,定義了兩種盤區(qū)類型,統(tǒng)一盤區(qū)和混合盤區(qū)。
其中:統(tǒng)一盤區(qū)只能存放同一個(gè)對(duì)象,該對(duì)象擁有這個(gè)盤區(qū)的所有頁面
混合盤區(qū):由多個(gè)對(duì)象共同擁有該盤區(qū)。
在實(shí)際為對(duì)象分配存儲(chǔ)盤區(qū)時(shí),為了提高空間利用率,默認(rèn)的情況下,如果一個(gè)對(duì)象一開始大小小于8個(gè)頁面,就盡量放在混合盤區(qū)中,如果該對(duì)象大小增加到8個(gè)頁面后,SQLSERVER會(huì)為這個(gè)對(duì)象重新分配一個(gè)統(tǒng)一盤區(qū)。
為了能夠通過上述策略來實(shí)現(xiàn)為對(duì)象分配存儲(chǔ)盤區(qū),SQLSERVER提供了GAM/SGAM機(jī)制來管理和維護(hù)數(shù)據(jù)文件的盤區(qū)信息。
Sql Server 區(qū)管理(GAM,SGAM)
大家都知道Sql Server 中數(shù)據(jù)文件存儲(chǔ)的最小單位是頁面(Page),但實(shí)際SQLSERVE并不是以頁面為單位給數(shù)據(jù)分配空間的,Sql Server默認(rèn)的存儲(chǔ)分配單位是盤區(qū)(Extend)。這樣做的主要原因是為了避免頻繁的讀寫IO,提升性能。在表或其它對(duì)象分配存儲(chǔ)空間,不是直接分配一個(gè)8K的頁面,而是以一個(gè)盤區(qū)(Extend)為存儲(chǔ)分配單位,一個(gè)盤區(qū)為8個(gè)頁面(Size = 8*8K=64K)。
這樣,對(duì)區(qū)得操作就會(huì)非常頻繁,也要求Sql Server有自己的一套系統(tǒng)管理著數(shù)量眾多的區(qū)。其中最突出的出一個(gè)問題,那就是在存儲(chǔ)那些只有少量數(shù)據(jù),不足8K的對(duì)象,如果也是分配給一個(gè)盤區(qū),就會(huì)存在存儲(chǔ)空間上的浪費(fèi),降低了空間分配效率。
為解決上述問題,SQLSERVER提供了一種解決方案,定義了兩種盤區(qū)類型,統(tǒng)一盤區(qū)和混合盤區(qū)。
全局分配映射表 (GAM)?:統(tǒng)一盤區(qū),GAM 頁記錄已分配的區(qū)。每個(gè) GAM 包含 64,000 個(gè)區(qū),相當(dāng)于近 4 GB 的數(shù)據(jù)。GAM 用一個(gè)位來表示所涵蓋區(qū)間內(nèi)的每個(gè)區(qū)的狀態(tài)。如果位為 1,則區(qū)可用;如果位為 0,則區(qū)已分配。?
共享全局分配映射表 (SGAM)?:由多個(gè)對(duì)象共同擁有該盤區(qū),SGAM 頁記錄當(dāng)前用作混合區(qū)且至少有一個(gè)未使用的頁的區(qū)。每個(gè) SGAM 包含 64,000 個(gè)區(qū),相當(dāng)于近 4 GB 的數(shù)據(jù)。SGAM 用一個(gè)位來表示所涵蓋區(qū)間內(nèi)的每個(gè)區(qū)的狀態(tài)。如果位為 1,則區(qū)正用作混合區(qū)且有可用頁。如果位為 0,則區(qū)未用作混合區(qū),或者雖然用作混合區(qū)但其所有頁均在使用中。?
在實(shí)際為對(duì)象分配存儲(chǔ)盤區(qū)時(shí),為了提高空間利用率,默認(rèn)的情況下,如果一個(gè)對(duì)象一開始大小小于8個(gè)頁面,就盡量放在混合盤區(qū)中,如果該對(duì)象大小增加到8個(gè)頁面后,SQLSERVER會(huì)為這個(gè)對(duì)象重新分配一個(gè)統(tǒng)一盤區(qū)。
據(jù)區(qū)當(dāng)前的使用情況,GAM 和 SGAM 中每個(gè)區(qū)具有以下位模式:
這將簡(jiǎn)化區(qū)管理算法。若要分配統(tǒng)一區(qū),數(shù)據(jù)庫引擎將在 GAM 中搜索為 1 的位,并將其設(shè)置為 0。若要查找具有可用頁的混合區(qū),數(shù)據(jù)庫引擎將在 SGAM 中搜索為 1 的位。若要分配混合區(qū),數(shù)據(jù)庫引擎將在 GAM 中搜索為 1 的位,將其設(shè)置為 0,然后將 SGAM 中對(duì)應(yīng)的位設(shè)置為 1。若要釋放區(qū),數(shù)據(jù)庫引擎確保將 GAM 位設(shè)置為 1,將 SGAM 位設(shè)置為 0。實(shí)際上,數(shù)據(jù)庫引擎內(nèi)部使用的算法比本主題中介紹的更為復(fù)雜,因?yàn)閿?shù)據(jù)庫引擎在數(shù)據(jù)庫中均勻分布數(shù)據(jù)。但是,由于無需管理區(qū)分配信息鏈,因此即使是實(shí)際算法也會(huì)被簡(jiǎn)化。
管理Sql Server可用空間
首先摘錄段 MSDN 的一段官方解釋:
頁可用空間 (PFS) 頁記錄每頁的分配狀態(tài),是否已分配單個(gè)頁以及每頁的可用空間量。PFS 對(duì)每頁都有一個(gè)字節(jié),記錄該頁是否已分配。如果已分配,則記錄該頁是為空、已滿 1% 到 50%、已滿 51% 到 80%、已滿 81% 到 95% 還是已滿 96% 到 100%。
將區(qū)分配給對(duì)象后,數(shù)據(jù)庫引擎將使用 PFS 頁來記錄區(qū)中的哪些頁已分配或哪些頁可用。數(shù)據(jù)庫引擎必須分配新頁時(shí),將使用此信息。保留的頁中的可用空間量?jī)H用于堆和 Text/Image 頁。數(shù)據(jù)庫引擎必須找到一個(gè)具有可用空間的頁來保存新插入的行時(shí),使用此信息。索引不要求跟蹤頁的可用空間,因?yàn)椴迦胄滦械狞c(diǎn)是由索引鍵值設(shè)置的。
在數(shù)據(jù)文件中,PFS 頁是文件頭頁之后的第一頁(頁碼為 1)。接著是 GAM 頁(頁碼為 2),然后是 SGAM 頁(頁碼為 3)。第一個(gè) PFS 頁之后是一個(gè)大小大約為 8,000 頁的 PFS 頁。在第 2 頁的第一個(gè) GAM 頁之后還有另一個(gè) GAM 頁(包含 64,000 個(gè)區(qū)),在第 3 頁的第一個(gè) SGAM 頁之后也有另一個(gè) SGAM 頁(包含 64,000 個(gè)區(qū))。下圖顯示了數(shù)據(jù)庫引擎用來分配和管理區(qū)的頁順序。
看過之后,讓人一頭霧水,真是不知所云,真佩服這些 MSDN 是如何翻譯的,看來中文 MSDN 太不靠譜,最后沒辦法,只能google了
其實(shí)上面說的意思就是:Sql Server 管理可用空間的方法是,查找每個(gè)每個(gè)頁面是否使用,以及使用情況情況。這時(shí)就需要一個(gè)頁面來記錄各個(gè)頁面的使用情況了,這就是 PFS 頁。
PFS(Page Free Space),也叫頁面自由空間,該頁面用來跟蹤一個(gè)文件中每一個(gè)特定的頁面的利用率情況。一個(gè)文件中第二個(gè)頁面(頁碼1)就是PFS頁面,該頁面的每個(gè)字節(jié)都記錄了相應(yīng)頁面的分配情況、頁面類型、是否IAM頁、是否包含刪除記錄、以及空間利用率信息;PFS能夠管理和跟蹤8088個(gè)頁面的使用情況,即接近64M的空間,以后每8088個(gè)頁面將再出現(xiàn)一次。
讓我們首先了解一下PFS的頁面管理字節(jié)的構(gòu)造,管理單位為字節(jié),每字節(jié)管理一個(gè)頁面。
第0個(gè)bit為保留字節(jié),始終為0
第1個(gè)bit表示該頁面是否已分配,我們知道GAM頁用來管理區(qū)是否已分配,但一個(gè)區(qū)包含8個(gè)頁面,所以用該bit用來準(zhǔn)確定位該區(qū)的某個(gè)頁面是否已分配出去了。
第2個(gè)bit表示該頁面是否混合分區(qū)的一個(gè)頁面。
第3個(gè)bit表示該頁面是否是一個(gè)IAM(索引分配映射)頁面。
第4個(gè)bit表示該頁面中是否包含幻影或已刪除記錄,這有助于SQL Server定期清理幻影或已刪除記錄。
第5~7個(gè)頁面表示該頁面的空間使用率情況。
統(tǒng)一區(qū)和混合區(qū)。
是管理空間的基本單位,一個(gè)區(qū)是8個(gè)物理上連續(xù)的頁的集合,所有頁都存儲(chǔ)在區(qū)中,SQLServer有兩種類型的區(qū)統(tǒng)一區(qū)和混合區(qū)。
用于數(shù)據(jù)存儲(chǔ)的連續(xù)的磁盤空間塊SQLServer,中數(shù)據(jù)存儲(chǔ)的基本單位是頁磁盤I或O操作在頁級(jí)執(zhí)行,頁的大小為8KB,每頁的開頭是96字節(jié)的頁頭,用于存儲(chǔ)有關(guān)頁的系統(tǒng)信息。