《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 列和两个固定长度列:
(
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');
可以看到:
现在,插入一行数据:
说明: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一点空间也不用。实际上,它仍然用了两个字节来存放了偏移数组。我们看一个例子:
(
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。
第四种存储方式:日期和时间格式
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"
你可以通过这个语句查看对应的日期:
结果为默认值:1900-01-01 00:00:00.0000000
第五种:SQL_variant 数据
在此略去。
关于存储行更多的信息,在后面的第七章学习中将继续展开。
下一节将继续学习列和行的存储相关操作。
《Microsoft Sql server 2008 Internals》读书笔记--第五章Table(6)相关推荐
- 《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(10)
<Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第八章The Query Optimizer(5)
<Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第五章Table(4)
<Microsoft Sql server 2008 Internals>索引目录: <Microsoft Sql server 2008 Internal>读书笔记--目录索 ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第十一章DBCC Internals(11)
<Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(3)
<Microsoft Sql server 2008 Internals>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397 ...
- 《Microsoft Sql server 2008 Internal》读书笔记--第八章The Query Optimizer(1)
<Microsoft Sql server 2008 Interna>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397.h ...
- 《Microsoft Sql server 2008 Internal》读书笔记--第七章Special Storage(3)
<Microsoft Sql server 2008 Interna>读书笔记订阅地址: http://www.cnblogs.com/downmoon/category/230397.h ...
- [MS]Microsoft SQL Server 2008 R2 开发版/企业版/标准版
Microsoft® SQL Server® 2008 R2 是一个功能强大且可靠的数据管理系统,它功能丰富,能保护数据,并且可改善嵌入式应用程序.轻型网站和应用程序以及本地数据存储区的性能. 数据中 ...
- 数据库备份还原顺序关系(环境:Microsoft SQL Server 2008 R2)
让新手们了解一下备份顺序 --1.塔建环境(生成测试数据和备份文件) /* 测试环境: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) ...
最新文章
- Cisco2811基本操作
- FineUI小技巧(5)向子窗口传值,向父窗口传值
- Spring AOP小记
- Dart是一个怎样的语言?
- PMCAFF微课堂(已结束) | 典典养车新媒体负责人亲授:如何运营百万级企业服务号
- 从程序员到项目经理(十一):每个人都是管理者
- 清除java_如何在Java地毯下有效地清除问题
- Mycat监控_监控平台安装Mycat-web_作为配置中心注册发现用---MyCat分布式数据库集群架构工作笔记0037
- Dropping Balls UVA - 679(二叉树的遍历)
- 【Spark Summit EU 2016】Spark的性能,过去、现在与未来
- (转)OpenStack Kilo 版本中 Neutron 的新变化
- 关于arcview 3.2 中输出图形添加坐标网格(Graticules and Measured Grids)时直接退出的问题...
- 软考数据库系统工程师复习资料(完全版)
- 常用端口号\协议\服务对照表
- MySQL数据库 单表数据记录查询
- 千兆路由器什么牌子好?家用千兆路由器2018排行!
- 多路电源管理芯片(记录)
- linux man 位置,Linux系统如何查看命令帮助,man命令使用详解
- GCD Expectation ZOJ - 3868 (容斥)
- 软件工程专业计算机毕设选题推荐
热门文章
- windows下phpstorm的常用快捷键及使用技巧
- js中substr,substring,indexOf,lastIndexOf,split 的用法
- 《Effective C#》Item 20:区分接口实现与虚函数重载
- 数据库的事务隔离级别
- 一名计算机专业新生代农民工的五年求学之路,从“低谷”到“山峰”
- 数据治理管理平台有哪些特点
- HTTP协议的请求协议(个人笔记看不懂的地方可以和我交流)
- html select ajax,AJAX 动态加载后台数据 绑定select的方法
- Danfo.js专题 - 附:Dnotebook(Danfo Notebook)单机资源与汉化文档
- python报表自动化系列 - 译码:将纯数字译码为Excel列坐标的字母索引表示形式