zoukankan      html  css  js  c++  java
  • 《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 列和两个固定长度列:

    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 数据

    在此略去。

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

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

    邀月注:本文版权由邀月和博客园共同所有,转载请注明出处。
    助人等于自助!  3w@live.cn
  • 相关阅读:
    jq实现简单的二级联动下拉框
    jq实现多选框及反选
    用js和css实现选项卡效果+jq(2019-10-09)
    python 创建类的实例对象
    selenium——获取元素的尺寸、文本信息、元素的属性、元素是否可见
    selenium——表单嵌套
    selenium控制浏览器
    类的应用
    零散的python知识点
    安装python2、python3
  • 原文地址:https://www.cnblogs.com/downmoon/p/1661074.html
Copyright © 2011-2022 走看看