《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 列和两个固定长度列:

CREATETABLE variable
(
Col1 char(3) NOTNULL,
Col2 varchar(250) NOTNULL,
Col3 varchar(5) NULL,
Col4 varchar(20) NOTNULL,
Col5 smallintNULL
);

SELECTobject_id, type_desc,
indexproperty(object_id, name, 'minlen') as minlen
FROM sys.indexes whereobject_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一点空间也不用。实际上,它仍然用了两个字节来存放了偏移数组。我们看一个例子:

CREATETABLE dbo.null_varchar
(
id INTPRIMARYKEYIDENTITY(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
INSERTINTO null_varchar(col10)
SELECT'a';
INSERTINTO null_varchar(col1)
SELECT'b';
INSERTINTO null_varchar
SELECT'','','','','','','','','','c';
INSERTINTO null_varchar
SELECT'd','','','','','','','','','';
GO

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

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

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

CREATETABLE 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

INSERTINTO 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"

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

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

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

第五种:SQL_variant 数据

在此略去。

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

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

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

  1. 《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(10)

    <Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...

  2. 《Microsoft Sql server 2008 Internals》读书笔记--第八章The Query Optimizer(5)

    <Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...

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

    <Microsoft Sql server 2008 Internals>索引目录: <Microsoft Sql server 2008 Internal>读书笔记--目录索 ...

  4. 《Microsoft Sql server 2008 Internals》读书笔记--第十一章DBCC Internals(11)

    <Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...

  5. 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(3)

    <Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...

  6. 《Microsoft Sql server 2008 Internal》读书笔记--第八章The Query Optimizer(1)

    <Microsoft Sql server 2008 Interna>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397.h ...

  7. 《Microsoft Sql server 2008 Internal》读书笔记--第七章Special Storage(3)

    <Microsoft Sql server 2008 Interna>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397.h ...

  8. [MS]Microsoft SQL Server 2008 R2 开发版/企业版/标准版

    Microsoft® SQL Server® 2008 R2 是一个功能强大且可靠的数据管理系统,它功能丰富,能保护数据,并且可改善嵌入式应用程序.轻型网站和应用程序以及本地数据存储区的性能. 数据中 ...

  9. 数据库备份还原顺序关系(环境:Microsoft SQL Server 2008 R2)

    让新手们了解一下备份顺序 --1.塔建环境(生成测试数据和备份文件) /* 测试环境: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) ...

最新文章

  1. Cisco2811基本操作
  2. FineUI小技巧(5)向子窗口传值,向父窗口传值
  3. Spring AOP小记
  4. Dart是一个怎样的语言?
  5. PMCAFF微课堂(已结束) | 典典养车新媒体负责人亲授:如何运营百万级企业服务号
  6. 从程序员到项目经理(十一):每个人都是管理者
  7. 清除java_如何在Java地毯下有效地清除问题
  8. Mycat监控_监控平台安装Mycat-web_作为配置中心注册发现用---MyCat分布式数据库集群架构工作笔记0037
  9. Dropping Balls UVA - 679(二叉树的遍历)
  10. 【Spark Summit EU 2016】Spark的性能,过去、现在与未来
  11. (转)OpenStack Kilo 版本中 Neutron 的新变化
  12. 关于arcview 3.2 中输出图形添加坐标网格(Graticules and Measured Grids)时直接退出的问题...
  13. 软考数据库系统工程师复习资料(完全版)
  14. 常用端口号\协议\服务对照表
  15. MySQL数据库 单表数据记录查询
  16. 千兆路由器什么牌子好?家用千兆路由器2018排行!
  17. 多路电源管理芯片(记录)
  18. linux man 位置,Linux系统如何查看命令帮助,man命令使用详解
  19. GCD Expectation ZOJ - 3868 (容斥)
  20. 软件工程专业计算机毕设选题推荐

热门文章

  1. windows下phpstorm的常用快捷键及使用技巧
  2. js中substr,substring,indexOf,lastIndexOf,split 的用法
  3. 《Effective C#》Item 20:区分接口实现与虚函数重载
  4. 数据库的事务隔离级别
  5. 一名计算机专业新生代农民工的五年求学之路,从“低谷”到“山峰”
  6. 数据治理管理平台有哪些特点
  7. HTTP协议的请求协议(个人笔记看不懂的地方可以和我交流)
  8. html select ajax,AJAX 动态加载后台数据 绑定select的方法
  9. Danfo.js专题 - 附:Dnotebook(Danfo Notebook)单机资源与汉化文档
  10. python报表自动化系列 - 译码:将纯数字译码为Excel列坐标的字母索引表示形式