国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > SQL Server > 正文

SQL Server 存儲(2/8):理解數(shù)據(jù)記錄結(jié)構(gòu)

2024-08-31 00:54:32
字體:
供稿:網(wǎng)友
SQL Server 存儲(2/8):理解數(shù)據(jù)記錄結(jié)構(gòu)

在SQL Server :理解數(shù)據(jù)頁結(jié)構(gòu)我們提到每條記錄都有7 bytes的系統(tǒng)行開銷,那這個7 bytes行開銷到底是一個什么樣的結(jié)構(gòu),我們一起來看下。

數(shù)據(jù)記錄存儲我們具體的數(shù)據(jù),換句話說,它存在堆表里,或者存在聚集索引的葉子節(jié)點。數(shù)據(jù)記錄結(jié)構(gòu)是為了讓SQL Server更高效的管理數(shù)據(jù)。我們來看下數(shù)據(jù)記錄結(jié)構(gòu)示意圖:

上圖中藍色部分是所有數(shù)據(jù)記錄部分(即系統(tǒng)行開銷,大小基于列個數(shù),等于或大于7 bytes),綠色部分是表結(jié)構(gòu)里取決于定長/變長列的數(shù)據(jù)記錄部分(實際存放的數(shù)據(jù),大小基于實際數(shù)據(jù))。

行頭系統(tǒng)數(shù)據(jù):

用做狀態(tài)位1的第1字節(jié)(8位)是用來定義記錄的屬性:

  • 第0位:版本信息,在SQL Server 2008里始終是0;
  • 第1-3位:這3位用來定義記錄類型;
    • 0 數(shù)據(jù)記錄(data record)
    • 1 轉(zhuǎn)發(fā)記錄(Forwarded record)
    • 2 轉(zhuǎn)發(fā)存根(a forwarding stub)
    • 3 索引記錄(Index record)
    • 4 二進制堆碎片或行溢出數(shù)據(jù)(blob fragment or row overflow data)
    • 5 鬼影索引記錄(Ghost index record)
    • 6 鬼影數(shù)據(jù)記錄(ghost data record)
    • 7 鬼影版本記錄(ghost version record)
  • 第4位:存在空值位圖(Null bitmap)或沒有。在SQL Server 2008里沒有不為空的列也會有空值位圖(Null bitmap);
  • 第5位:表示是否存在變長列;
  • 第6位:表示該列包含版本信息;
  • 第7位:在SQL Server里未使用;

用作狀態(tài)位2的第2字節(jié)(8位)。只有1位用來表示這條記錄是否為鬼影轉(zhuǎn)發(fā)記錄(ghost forwarded record)。

由行頭開始到定長列結(jié)尾長度:

下2個字節(jié)用來存儲行頭開始到定長列結(jié)尾長度。它包含2個狀態(tài)位,2個字節(jié)用作這個列表示在表中定長數(shù)據(jù)的實際長度。例如如果表里沒有定長列,這個列的值會是4。這和頁頭列pminlen顯示的值是一樣的。

所有定長列字段值(Fixed_Data_Size):

下n個字節(jié)用來存儲在表中的定長數(shù)據(jù),n就是在表中所有定長列的長度。如果表里的所有列都是變長列,這一部分就沒有。

空值位圖(Null_Bitmap):

下2個字節(jié)用來存儲表里的列數(shù)。

下n個字節(jié)用作空值位圖,每個bit對應(yīng)一個列,1表示對應(yīng)列為空。n的值為:列數(shù) / 8,將值取整。

Variable_Data_Size:

下2個字節(jié)用來存儲表里變長列個數(shù)。

下n個字節(jié)用來存儲每個變長列結(jié)束為止的偏移量。每個變長列需要2字節(jié),n的值為:變長列數(shù) * 2 。

最后n個字節(jié)用來存儲所有變長列值,n的值為所有變長列的實際長度的總長度。

我們來看一個具體的例子:

創(chuàng)建數(shù)據(jù)庫,并插入2條記錄

 1 USE [InternalStorageFormat] 2 GO 3  4 IF EXISTS ( SELECT  * 5             FROM    sysobjects 6             WHERE   id = OBJECT_ID(N'[dbo].[Customers]') 7                     AND OBJECTPROPERTY(id, N'IsUserTable') = 1 ) 8     DROP TABLE dbo.Customers 9 10 CREATE TABLE Customers11 (12    FirstName CHAR(50) NOT NULL,13    LastName CHAR(50) NOT NULL,14    Address CHAR(100) NOT NULL,15    ZipCode CHAR(5) NOT NULL,16    Rating INT NOT NULL,17    ModifiedDate DATETIME NOT NULL,18 )19 GO20 21 22 INSERT INTO dbo.Customers23         ( FirstName ,24           LastName ,25           Address ,26           ZipCode ,27           Rating ,28           ModifiedDate29         )30 VALUES  ( 'Woody' , -- FirstName - char(50)31           'Tu' , -- LastName - char(50)32           'ZUOQIAO YOUXI TOWN LINHAI CITY' , -- Address - char(50)33           '0000' , -- ZipCode - char(5)34           1 , -- Rating - int35           '2015-05-07 10:09:51'  -- ModifiedDate - datetime36         )37         go 2

使用DBCC IND命令查看表對應(yīng)頁列表:

1 DBCC IND('InternalStorageFormat','Customers',-1)

我們看到數(shù)據(jù)頁號為79。

使用DBCC PAGE命令查看頁信息:

1 DBCC TRACEON(3604)2 DBCC PAGE(InternalStorageFormat,1,79,3)3 GO  

在頁頭pminlen的值是221,包括定長列的總長217 bytes(50+50+100+5+4+8),2 bytes用作狀態(tài)位(行頭系統(tǒng)開銷),2 byte 用作由行頭開始到定長列結(jié)尾長度。

在記錄槽提到的長度224,包括頁頭pminlen的值,1 byte用作空值位圖(6/8 取整為1)和2 bytes 的字段個數(shù)。

我們來看一個變長列的表。

創(chuàng)建表并插入數(shù)據(jù)后,查看表對應(yīng)的頁:

 1 CREATE TABLE VariableLength( 2    Title         CHAR(10) NOT NULL, 3    FirstName     VARCHAR(100), 4    Lastname      VARCHAR(100), 5    email         VARCHAR(50),  6    dob           date NOT NULL, 7    phone         CHAR(10), 8    Countrycode   CHAR(3), 9    Designation   VARCHAR(100),10    PersonalPreference VARCHAR(100)11 )12 GO13 INSERT INTO VariableLength VALUES ('Mr','Woody','Tu','smartgz@QQ.com','2015-5-7','XXXXXXXXXX','Chn','DBA','Nothing Spl')14 GO15 DBCC IND('InternalStorageFormat','VariableLength',-1)

我們看到數(shù)據(jù)頁號為202。

使用DBCC PAGE命令查看頁信息:

1 DBCC TRACEON(3604)2 GO3 DBCC PAGE('InternalStorageFormat',1,202,3)--記得根據(jù)你的實際數(shù)據(jù)庫,修改頁號202

pminlen值為30,包含:

  • 1 byte 狀態(tài)位1
  • 1 byte 狀態(tài)為2
  • 2 bytes 存儲行頭開始到定長列結(jié)尾長度
  • 26 bytes 所有定長列總長度(10+3+10+3:tittle,dob,phone,countrycode)
    • Title CHAR(10) NOT NULL

    • dob date NOT NULL

    • phone CHAR(10)

    • Countrycode CHAR(3)

可以用下列語句驗證下定長列總長度:

1 SELECT DATALENGTH(Title) title,DATALENGTH(dob) dob,DATALENGTH(phone) phone,DATALENGTH(Countrycode) countrycode FROM VariableLength

在槽0顯示的81長度包含:

  • 1 byte 狀態(tài)位1
  • 1 byte 狀態(tài)為2
  • 2 bytes 存儲行頭開始到定長列結(jié)尾長度
  • 26 bytes 所有定長列總長度(10+3+10+3:tittle,dob,phone,countrycode)
    • Title CHAR(10) NOT NULL

    • dob date NOT NULL

    • phone CHAR(10)

    • Countrycode CHAR(3)

  • 2 bytes 存儲列個數(shù)
  • 2 bytes 用作空值位圖,字段個數(shù)/8后取整,即 9/8 得到2
  • 2 bytes 存儲變長列個數(shù)
  • 10 bytes 用來存儲每個變長列結(jié)束位置的偏移量 變長列個數(shù) * 2,即 5 * 2 得到10,5個變長列包含:
    • FirstName VARCHAR(100)

    • Lastname VARCHAR(100)

    • email VARCHAR(50)

    • Designation VARCHAR(100)

    • PersonalPreference VARCHAR(100)

  • 35 bytes 用來存儲所有變長列的實際長度,這個可以使用下列語句得到
1 SELECT DATALENGTH(FirstName)+DATALENGTH(Lastname)+DATALENGTH(email)+2 DATALENGTH(Designation)+DATALENGTH(PersonalPreference) FROM VariableLength

總結(jié)下每條記錄的系統(tǒng)行開銷:

行頭系統(tǒng)數(shù)據(jù)(2 bytes)+由行頭開始到定長列結(jié)尾長度(2 bytes)+列個數(shù)(2 bytes)+空值位圖數(shù)據(jù)(取整(列個數(shù)/8) n bytes)

2 bytes + 2 bytes + 2 bytes + 取整(列個數(shù)/8)

當(dāng)列個數(shù)小于等于8時,系統(tǒng)行開銷始終是7 bytes,往上沒增加8列,增加1 bytes,即系統(tǒng)系統(tǒng)行開銷始終大于等于7 bytes

對于在SQL Server里數(shù)據(jù)記錄的存儲格式,希望你已經(jīng)有了清晰的認識。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 班玛县| 祁阳县| 闻喜县| 新营市| 阿拉善左旗| 青神县| 阿克| 建宁县| 石棉县| 且末县| 万荣县| 门源| 通山县| 稷山县| 蛟河市| 雅安市| 体育| 阿巴嘎旗| 盈江县| 嘉善县| 白朗县| 类乌齐县| 昆明市| 潞西市| 日照市| 磐安县| 稷山县| 琼海市| 沾化县| 高淳县| 迁西县| 宜良县| 民和| 红原县| 武邑县| 武乡县| 宝清县| 延寿县| 肥城市| 石台县| 东辽县|