1. 程式人生 > >sql server 存儲機制

sql server 存儲機制

一個 window tle 測試表 最大 inf windows 文件 單元

1、區段

  區段(extent)是用來為表和索引分配空間的基本存儲單元。它由8個連續的64KB數據頁組成。

  基於區段(而不是實際使用空間)分配空間的概念的要點:

  1.   一旦區段已滿,那麽下一記錄將要占據的空間不是記錄的大小,而是整個新區段的大小。一次分配一個區段而不是分配一個記錄。
  2.   通過預分配空間,SQL Server節省為每個記錄分配新空間的時間。

  向當前分配的區段添加了過多的行就要占用整個區段,看起來是一種浪費,但是這種方法浪費的空間不多。但是,這些浪費的空間會累加,特別是在碎片較多的環境中。

  占據所有空間的好處是SQL Server省去了一些分配時間的系統開銷,不需在每次寫入行時都考慮分配問題,SQL Server僅僅當需要新區段時才處理額外的空間分配。

  不要將區段占用的空間和數據庫占用的空間想混淆,分配給數據庫的那些空間就是磁盤驅動器將要減少的可用空間。區段僅僅是在又數據庫保留的整個空間內再次進行分配的方式。

  2、頁

  頁是特定區段中的分配單元。每個區段包含8頁。

  也是在到達實際數據行前所能達到的最後一個存儲級別。盡管每個區段中的頁數是固定的,但是每一頁中的行數不是固定的。這取決於行的大小,而行的大小是可以變化的。可以把頁看做是表行和索引行數據的容器。通常不允許跨行。

  常用的頁類型:

  1、數據頁:數據也是不需解釋的-它們是表中的實際數據,但任何沒有用text in row選項、varchar(max)或varbinary(max)定義的BLOB數據除外。

  2、索引頁:索引頁也是相當直觀-它們既包括非群集索引的非頁級和頁級頁,又包括群集索引的非頁級頁。

  在SQL SERVER中,存儲的最小單位是頁。SQL SERVER對於頁的讀取,要麽整個讀取,要麽完全不讀取,沒有折中。

  數據庫頁的大小是8K,實際能夠存儲的數據量為1024*8=8192-頁頭(96)-行偏移(36)=8060字節。

  頁拆分

  當頁滿時,它會進行拆分。這意味著多個新頁被分配-也意味著現有頁上又近半的數據被移到新頁上。

  在使用群集索引時,會有例外。如果有一個群集索引,並且下一個插入的記錄在物理上將作為表中的最後一個記錄,那麽創建一個新頁,然後將該新行添加到這個新頁中,而不需要重新定位任何現有數據。

  3、行

  行就是表中的一行記錄。行最大可達8KB。除了8060字符限制外,還有最大1024標準列(非稀疏列)的限制,列就是表的一列數據,就是你理解的列。實際上,突破8060字符限制前用完列的情況不多見。1024提供了小於8字節的平均列寬度。1024個列,一個表通常才十幾個列啊。當突破了1024個列時,就要運用到稀疏列。

  4、稀疏列

  稀疏列是SQL Server2008新引入的一種特殊的數據結構。它們主要用於處理重復的場景,其中的列只是偶爾會用到。大部分時候為空。許多時候,一旦遇到少量這類列,就意味著以後可能會遇到大量這類列。使用稀疏列,可以將單個表中允許的列的總數提高到30000。30000個列,什麽概念?什麽系統用得到這麽多列。

  Image、text、ntext、geography、geometry、timestamp和所有用戶自定義數據類型不能被標記為稀疏列。

在SQL Server中,數據的存儲以頁為單位。八個頁為一個區。一頁為8K,一個區為64K,這個意味著1M的空間可以容納16個區。如圖1所示:

技術分享圖片

圖1.SQL Server中的頁和區

如圖1(PS:發現用windows自帶的畫圖程序畫博客中的圖片也不錯技術分享圖片)可以看出,SQL Server中的分配單元分為三種,分別為存儲行內數據的In_Row_Data,存儲Lob對象的LOB_Data,存儲溢出數據的Row_Overflow_data。下面我們通過一個更具體的例子來理解這三種分配單元。

我建立如圖2所示的表。

技術分享圖片

圖2.測試表

圖2的測試表不難看出,通過插入數據使得每一行的長度會超過每頁所能容納的最大長度8060字節。使得不僅產生了行溢出(Row_Overflow_Data),還需要存儲LOB的頁.測試的插入語句和通過DBCC IND看到的分配情況如圖3所示。

技術分享圖片

圖3.超過8060字節的行所分配的頁

除去IAM頁,這1行數據所需要三個頁來存儲。首先是LOB頁,這類是用於存儲存在數據庫的二進制文件所設計,當這個類型的列出現時,在原有的列會存儲一個24字節的指針,而將具體的二進制數據存在LOB頁中,除去Text之外,VarBinary(max)也是存在LOB頁中的。然後是溢出行,在SQL Server 2000中,一行超過8060字節是不被允許的,在SQL Server 2005之後的版本對這個特性進行了改進,使用Varchar,nvarchar等數據類型時,當行的大小不超過8060字節時,全部存在行內In-row data,當varchar中存儲的數據過多使得整行超過8060字節時,會將額外的部分存於Row-overflow data頁中,如果update這列使得行大小減少到小於8060字節,則這行又會全部回到in-row data頁。

sql server 存儲機制