1. 程式人生 > >實驗證明SQL SERVER中的NULL值是否佔用儲存空間。

實驗證明SQL SERVER中的NULL值是否佔用儲存空間。

本學期有一門資料庫管理的課程,老師最近在教學平臺上釋出了一道作業——SQL SERVER中的NULL值是否佔用儲存空間?

該作業要求學生用實驗證明自己的結論。現在把整個實驗證明過程記錄如下。

一、過程

1、首先建立一個數據庫為Test_hedong,並在該資料庫下建立兩個表,一個表為fixed_hedong,其中包括三個欄位,允許為NULL值的字

      段為定長欄位。另一個表variable_hedong包含四個欄位,包括允許為NULL值在內的欄位有三個變長欄位。隨後向兩個表中分別插入一

      條資料,允許為NULL值的欄位都插入NULL值。程式碼如下。

USE Test_hedong
GO
create table fixed_hedong
(
col1_hedong INT not null,
col2_hedong char(10) not null,
col3_hedong char(3) null,
)

create table variable_hedong
(
col1_hedong INT not null,
col2_hedong varchar(7) not null,
col3_hedong varchar(3) null,
col4_hedong varchar(10) not null
)
GO
insert into fixed_hedong values(123,'hedong',NULL)
insert into variable_hedong values(123,'hedong',null,'hedong')
GO

2、在查詢中輸入以下DBCC指令,其中第二行指令中的第一個引數為資料庫名,第二個引數為資料庫物件名,這裡為第一張表的名字。

      不出錯的話會得到如圖的file_id和page_id的值,分別為1,21

dbcc traceon(3604)
dbcc extentinfo(Test_hedong,fixed_hedong)

3、再輸入以下DBCC指令,第一個引數為資料庫名,第二個引數為file_id,第三個引數為page_id,最後一個引數輸入2就可以了。將會得 

      到如圖的結果:

dbcc page(Test_hedong,1,21,2)

    看到右邊“hedong”了嗎?它左邊的資料就是我們剛才插入的資料(10001500 7b000000 6865646f 6e672020 20200000 00030004),

    將它記錄下來,待會兒分析會用到。

4、現在來看第二張表,同樣的方法輸入DBCC指令,將表名改為第二張表的名字,此時又會得到另一個file_id和page_id,分別為1,55。

dbcc extentinfo(Test_hedong,variable_hedong)

5、再輸入以下DBCC指令,將會得到如圖的結果:

dbcc page(Test_hedong,1,55,2)

      看見右邊的"hedonghedong"了嗎?這就是剛才在第二張表插入的資料,它左邊的資料(30000800 7b000000 04000403 00190019

      001f0068 65646f6e 67686564 6f6e67)記錄下來,待會用來分析。

二、分析:

  1. 存放NULL值為定長欄位的資料行:

    10001500 7b000000 6865646f 6e672020 20200000 00030004

    其中”10”為狀態位A,它的值是0X10,二進位制表示為0001 0000,可看出只有位4是1,其他位都是0,所以該記錄

    沒有變長欄位。後面”00”是在記錄中未用。”1500”交換位元組後是0X0015,值為21,代表找到欄位數的位置在21字

    節之後。”7b000000”為col1_hedong資料,即123。”6865646f 6e6720202020”為col2_hedong資料,即”hedong”,

    後面的20202020代表空格,因為該欄位為定長char(10)。再後面”000000”即代表NULL值,可看出他是佔用了儲存

    空間的。”0300”即是在21位元組之後,它代表的是欄位數,交換位元組後是0X0003,代表存在3個欄位。最後04是

    NULL點陣圖,二進位制表示為0100,只有第三位是1,表示第3個欄位是NULL。

  2. 存放NULL值為變長欄位的資料行:

    30000800 7b000000 04000403 00190019 001f0068 65646f6e 67686564 6f6e67

    其中”30”是狀態位A,它的二進位制表示為0011 0000,可看出位4和位5是1,所以存在變長欄位。後面”00”在該記錄中未用。

    ”0800”交換位元組後是0X0008,十進位制表示8,即為在第8位元組之後找到欄位數。”7b000000”為col1_hedong資料,即123。

    ”0400”即是欄位數,交換位元組後為0X0004,表示存在4個欄位。04是NULL點陣圖,二進位制表示為0100,只有第三位是1,

    表示第3個欄位是NULL。後面”0300”是變長欄位數,交換位元組後是0X0003,表示有3個變長欄位。”1900”表示第一個變

    長欄位結束位置,再後面”1900”表示第二個變長欄位結束位置。這裡可看出第二個變長欄位實際長度為0,表示沒有任何

    資料儲存在變長資料區域,所以可知該變長欄位值為NULL值。”1f00”為第三個變長欄位結束位置。後面兩個” 6865646f

    6e67”分別為col2_hedong欄位和col3_hedong欄位的值。

所以可得出結論:在SQL SERVER中,定長記錄的NULL值佔用儲存空間,而變長記錄的NULL值

不佔用儲存空間。