1. 程式人生 > >第十二周翻譯-《Pro SQL Server Internals, 2nd edition》

第十二周翻譯-《Pro SQL Server Internals, 2nd edition》

開始 serve 影響 文件中 交換 對象 必須 family 排序

《Pro SQL Server Internals, 2nd edition》

作者:Dmitri Korotkevitch

翻譯:賴慧芳

譯文:

專業SQL服務器內部

了解在引擎蓋下發生了什麽,以及它是如何影響你的

第二版

數據頁和數據行

數據庫中的空間被劃分為邏輯8KB頁面。這些頁面從0開始連續編號,可以通過指定文件ID和頁碼來引用它們。頁面編號總是連續的,這樣當SQL Server增長數據庫文件時,新頁面的編號將從文件中最高的頁碼加1開始。類似地,當SQL Server壓縮文件時,它會從文件中刪除數量最多的頁面。

數據存儲在SQL SERVER

一般來說,SQL Server存儲和處理數據庫中的數據有三種不同的方式或技術。使用傳統的基於行存儲,數據存儲在數據行中,這些數據行將來自所有列的數據組合在一起。

SQL Server 2012引入了新的列存儲索引和基於列的存儲。這種技術以每列而不是每行存儲數據。我們將在本書的第七部分介紹基於列的存儲。

最後,SQL Server 2014中引入了內存內技術,而且SQL Server 2016中進一步改進了內存內技術。盡管出於冗余目的,它們將數據保存在磁盤上,但它們的存儲格式與基於行和基於列的存儲都有很大不同。我們將在本書的第8部分中討論內存技術。

本書的這一部分主要討論基於行的存儲和經典的B-樹索引和堆

1-6顯示了數據頁的結構。

1 - 6.數據頁結構

技術分享圖片

一個96字節的頁眉包含信息頁面的各個部分,如對象頁面所屬的行數和可用空閑空間頁面,鏈接到前一個和後一個頁面

,如果頁面在一個索引頁鏈,等等。頁眉後面是實際數據存儲的區域。然後是自由空間。最後,還有一個數組,它是一個由兩個字節的條目組成的塊,指示對應的數據行在頁面上開始時的偏移量。

數組表示頁面上數據行的邏輯順序。如果頁面上的數據需要按照索引鍵的順序排序,SQL Server不會對頁面上的數據行進行物理排序,而是根據索引排序順序填充數組。槽0(1-6最右邊)存儲頁上鍵值最低的數據行的偏移量;1,第二低的鍵值;等等。我們將在下一章更深入地討論索引。

SQL Server提供了一組豐富的系統數據類型,可以在邏輯上分為兩組:固定長度組和可變長度組。固定長度的數據類型,如intdatetimechar和其他類型,不管它們的值是多少,都使用相同數量的存儲空間,即使是

NULL也是如此。例如,int列總是使用4字節,而nchar(10)列總是使用20字節存儲信息。相反,可變長度的數據類型,如varcharvarbinary和其他一些類型,使用的存儲空間與存儲數據所需的空間一樣多,外加兩個字節。例如,nvarchar(4000)列僅使用12字節存儲5個字符的字符串,在大多數情況下,使用2字節存儲NULL值。我們將在本章後面討論變長列不為NULL值使用存儲空間的情況。

讓我們看看數據行的結構,如圖1-7所示。

1章■數據存儲內部

技術分享圖片

1 - 7.數據行結構

行的前兩個字節,稱為狀態位A和狀態位B,是位圖,其中包含關於行的信息,比如行類型,如果行已經被邏輯刪除(重定向),如果行有NULL值、可變長度列和版本控制標記。

行中接下來的兩個字節用於存儲數據的固定長度部分的長度。然後是固定長度的數據本身。

在固定長度的數據部分之後,有一個null位圖,它包含兩個不同的數據元素。第一個雙字節元素是行中的列數。第二個是空位圖數組。這個數組對表的每一列使用一位,不管它是否為空。

空位圖總是出現在堆表或聚集索引葉行的數據行中,即使表沒有可空列。但是,當索引中沒有可空列時,空位圖不會出現在非葉索引行中,也不會出現在非聚集索引的葉級行中。

位圖之後,是行中可變長度的數據部分。它從行中可變長度列的兩個字節數開始,然後是列偏移量數組。SQL Server為行中每個變長列存儲一個2字節偏移量值,即使該值為。然後是數據的實際可變長度部分。最後,行末尾有一個可選的14字節版本控制標記。此標記用於需要行版本控制的操作,例如在線索引重建、樂觀隔離級別和觸發器

註意,我們將在第6章討論索引維護,在第9章討論觸發器,在第21章討論樂觀隔離級別。

讓我們創建一個表,用一些數據填充它,並查看實際的行數據。代碼如清單1-4所示。復制函數將第一個參數提供的字符重復10次。

清單1 - 4.數據行格式:表創建

一個未文檔化但眾所周知的DBCC IND命令返回關於表分頁分配的信息。您可以在圖1-8中看到該命令的輸出。

技術分享圖片

1-8DBCC IND輸出

有兩頁是屬於這個表的。第一個頁面類型為10,是一種特殊類型的頁面,稱為IAM分配映射。這個頁面跟蹤屬於特定對象的頁面。但是,現在不要專註於此,因為我們將在本章後面討論分配映射頁面。

註意:SQL Server 2012引入了另一個未文檔化的數據管理功能(DMF)sys.dm_db_database_page_assignments,它可以用作DBCC IND命令的替代。與DBCC IND相比,此DMF的輸出提供了更多信息,並且可以與其他系統dmv或者目錄視圖連接。

PageType=1的頁面是包含數據行的實際數據頁。PageFIDPagePID列顯示了頁面的實際文件和頁碼。您可以使用另一個未文檔化的命令DBCC PAGE來檢查其內容,如清單1-5所示。

清單1 - 5.數據行格式:DBCC頁調用

清單1-6顯示了對應於第一行數據的DBCC頁面的輸出。SQL Server以字節交換的順序存儲數據。例如,兩個字節的值0001將存儲為0100

清單1 - 6.第一行的DBCC頁面輸出

1 - 9.第一個數據行

技術分享圖片

正如您所看到的,行以兩個狀態位開始,然後是兩個字節的值0800。這是字節交換值0008,它是行中列數屬性的偏移量。這個偏移量告訴SQL Server行中固定長度的數據部分在哪裏結束。

接下來的4個字節用於存儲固定長度的數據,在我們的示例中是ID列。然後是兩個字節的值,該值顯示數據行有四列,然後是一個一個字節的空位圖.如果只有四列,位圖中的一個字節就足夠了。它以二進制格式存儲04的值,即00000100。它表示行中的第三列包含空值。

接下來的兩個字節存儲行中可變長度列的數量,即3(字節順序為0300)。它後面是一個偏移量數組,其中每兩個字節存儲可變長度列數據結束的偏移量。如您所見,即使Col2NULL,它仍然使用偏移數組中的插槽。最後,還有來自可變長度列的實際數據。

現在,讓我們看看第二個數據行。清單1-7顯示DBCC頁面輸出,圖1-10顯示行數據。

技術分享圖片

1 - 10.第二數據行數據

清單1 - 7.DBCC頁輸出為第二行

第二行中的NULL位圖表示二進制值00001010,這表明Col1Col3NULL。即使表有三個可變長列,行中可變長列的數量表明偏移數組中只有兩列/槽。SQL Server不維護行中尾隨的空變長列的信息。

提示:您可以通過創建表來減少數據行的大小,方法是將通常存儲null值的變長列定義為CREATE TABLE語句中的最後一列。這是CREATE TABLE語句中列的順序惟一重要的情況。

固定長度的數據和內部屬性必須適合單個數據頁上可用的8060字節。如果不是這樣,SQL Server不允許您創建表。例如,清單1-8中的代碼產生了一個錯誤。

第十二周翻譯-《Pro SQL Server Internals, 2nd edition》