《Microsoft Sql server 2008 Internals》读书笔记--第五章Table(6)

 

《Microsoft Sql server 2008 Internals》读书笔记订阅地址:

http://www.cnblogs.com/downmoon/category/230397.html/rss

《Microsoft Sql server 2008 Internals》索引目录:

《Microsoft Sql server 2008 Internal》读书笔记--目录索引

 

上篇文章中提到五种典型的存储结构:一、固定长度的行;二、可变长度的行;三、Null和可变长度列;四、时间和日期数据;五、SQL_variant 数据。今天我们继续来看可变长度的行的存储:可变长度的列要比固定长度的列的存储复杂一些。

我们先来测试一个表Variable,有三个variable 列和两个固定长度列:

CREATE TABLE variable
(
Col1
char ( 3 ) NOT NULL ,
Col2
varchar ( 250 ) NOT NULL ,
Col3
varchar ( 5 ) NULL ,
Col4
varchar ( 20 ) NOT NULL ,
Col5
smallint NULL
);

SELECT object_id , type_desc,
indexproperty ( object_id , name, ' minlen ' ) as minlen
FROM sys.indexes where object_id = object_id ( ' variable ' );

SELECT name, column_id, max_inrow_length, pc.system_type_id, leaf_offset
FROM sys.system_internals_partition_columns pc
JOIN sys.partitions p
ON p.partition_id = pc.partition_id
JOIN sys.columns c
ON column_id = partition_column_id AND c. object_id = p. object_id
WHERE p. object_id = object_id ( ' variable ' );

可以看到:
邀月工作室

现在,插入一行数据:

INSERT variable VALUES ( ' AAA ' , REPLICATE ( ' X ' , 250 ), NULL , ' ABC ' , 123 );

说明:REPLICATE函数仅仅填充了250个X到col2,很有用的一个函数哟,特别在填充测试数据的时候。

我们可以按照前一篇所述的方法来查看data pages的存储状况:
邀月工作室

简要说明:

1、还记得前面学过的存放顺序吗?先固定列,再可变列。所以Col1和Col5要先存储,并且偏移量为正值,而col2\Col3\col4偏移量分别是-1,-2,-3。正好表示它们分别是可变列的第一、第二、第三个序号。

2、0500表示该行有5列。

3、04代表null Bitmap没有使用。

4、0300代表共有三个可变长度的列。

5、0e01代表第一个可变列的结束位置,与第二个可变列的位置相同。这是为什么呢?可能有人猜出来了,因为插入的是Null,所以实际上并没有数据存储到行中。这与固定长度的行不同。固定长度的行,Null值也占用存储空间。

6、该行数据的总长度为273字节,计算方法是0X1101,经过字节换算,应该是0X0111=273

那么,存储这行数据到底用去多少空间呢?可变长度列意味着更大的开销(overhead),它们的实际长度是无法预测的。即便对于固定长度的列,开销的数量也会取决于表中列的数量。记住:Null bitmap必须有足够的空间来存放每列的bit值。此外,每行还必须包含2个字节overhead和行底部的行偏移量数组

再来看第三种存储:Null和可变长度列

可能,有人看了上面的图会说,可变长度的列既然并不存放实际数据,那么应该不会占用空间。可为什么每个可变列还是有2个字节的偏移呢?这个-2是从哪儿来的呢?

因此,我们不能说SQL Server一点空间也不用。实际上,它仍然用了两个字节来存放了偏移数组。我们看一个例子:

CREATE TABLE dbo.null_varchar
(
id
INT PRIMARY KEY IDENTITY ( 1 , 1 ),
col1
VARCHAR ( 10 ) NULL ,
col2
VARCHAR ( 10 ) NULL ,
col3
VARCHAR ( 10 ) NULL ,
col4
VARCHAR ( 10 ) NULL ,
col5
VARCHAR ( 10 ) NULL ,
col6
VARCHAR ( 10 ) NULL ,
col7
VARCHAR ( 10 ) NULL ,
col8
VARCHAR ( 10 ) NULL ,
col9
VARCHAR ( 10 ) NULL ,
col10
VARCHAR ( 10 ) NULL
);
GO

SET NOCOUNT ON
INSERT INTO null_varchar(col10)
SELECT ' a ' ;
INSERT INTO null_varchar(col1)
SELECT ' b ' ;
INSERT INTO null_varchar
SELECT '' , '' , '' , '' , '' , '' , '' , '' , '' , ' c ' ;
INSERT INTO null_varchar
SELECT ' d ' , '' , '' , '' , '' , '' , '' , '' , '' , '' ;
GO

邀月工作室

从红色部分显示,0x03fe意味着0000001111111110,从右往左看,第一列是not Null,第10列是not Null,其余列是Null。共11列,后5列被忽略了。

同理:0x07fc意味着0000011111111100,从右往左看,第一列和第二列是not Null,其余列是Null。

第四种存储方式:日期和时间格式

CREATE TABLE times (
a
char ( 1 ),
dt1
datetime ,
b
char ( 1 ),
sd
smalldatetime ,
c
char ( 1 ),
dt2 datetime2,
d
char ( 1 ),
dt date,
e
char ( 1 ),
dto datetimeoffset,
f
char ( 1 ),
t time,
g
char ( 1 ),
t0 time(
0 ),
h
char ( 1 ),
t1 time(
1 ),
i
char ( 1 ),
t2 time(
2 ),
j
char ( 1 ),
t3 time(
3 ),
k
char ( 1 ),
t4 time(
4 ),
l
char ( 1 ),
t5 time(
5 ),
m
char ( 1 ),
t6 time(
6 ),
n
char ( 1 ),
t7 time(
7 ));
GO


INSERT INTO times
SELECT
' a ' , ' 01:02:03.123 ' ,
' b ' , ' 01:02:03.123 ' ,
' c ' , ' 01:02:03.123 ' ,
' d ' , ' 01:02:03.123 ' ,
' e ' , ' 01:02:03.123 ' ,
' f ' , ' 01:02:03.123 ' ,
' g ' , ' 01:02:03.123 ' ,
' h ' , ' 01:02:03.123 ' ,
' i ' , ' 01:02:03.123 ' ,
' j ' , ' 01:02:03.123 ' ,
' k ' , ' 01:02:03.123 ' ,
' l ' , ' 01:02:03.123 ' ,
' m ' , ' 01:02:03.123 ' ,
' n ' , ' 01:02:03.123 ' ;

邀月工作室
需要说明的是:

对于datatime和smalldatetime,存储值为0意味着日期是'1900-01-01",对于其他类型的日期值为693595意味着日期是"0001-01-01"

你可以通过这个语句查看对应的日期:

SELECT DATEADD (dd, 693595 , CAST ( ' 0001/1/1 ' AS datetime2));

结果为默认值:1900-01-01 00:00:00.0000000

第五种:SQL_variant 数据

在此略去。

关于存储行更多的信息,在后面的第七章学习中将继续展开。

下一节将继续学习列和行的存储相关操作。

转载于:https://www.cnblogs.com/downmoon/archive/2010/02/01/1661074.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值