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


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

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

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

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

     

    前面我们学习了数据页 的存储结构以及如何检查一个data page。那么如何查询一个物理页呢?

    记得在上篇文章时,我们介绍了了一个未公开的DBCC PAGE命令。该命令前需要知道页的具体参数,如
    --查询testdb数据库的第一个文件的第157页的数据页
    --DBCC PAGE (testdb,1,157,1);

    那么,如何查询第一页(first_page)的值呢?我们来看一个例子:假定我们创建一个表Fixed,语句如下:

    CREATETABLE Fixed
    (
    Col1
    char(5) NOTNULL,
    Col2
    intNOTNULL,
    Col3
    char(3) NULL,
    Col4
    char(6) NOTNULL
    );
    INSERT Fixed VALUES ('ABCDE', 123, NULL, 'CCCC');

    用下列语句,可以查询Fixed表的first_page的值。

    SELECTobject_name(object_id) AS name,
    rows, type_desc
    as page_type_desc,
    total_pages
    AS pages, first_page
    FROM sys.partitions p JOIN sys.system_internals_allocation_units a
    ON p.partition_id = a.container_id
    WHEREobject_id=object_id('dbo.Fixed');

    结果为:
    name    rows    page_type_desc    pages    first_page
    Fixed    1    IN_ROW_DATA    2    0xEE0000000100

    我们将这个十六进制结果转化一下,00 10 00 00 00 EE。

    前两个group代表一个2字节的文件数。这里是0x0001,页数是00EE,十进制是。可以通过一个function来转换。

    CREATEFUNCTION convert_page_nums (@page_numbinary(6))
    RETURNSvarchar(11)
    AS
    BEGIN
    RETURN(convert(varchar(2), (convert(int, substring(@page_num, 6, 1))
    *power(2, 8)) +
    (
    convert(int, substring(@page_num, 5, 1)))) +':'+
    convert(varchar(11),
    (
    convert(int, substring(@page_num, 4, 1)) *power(2, 24)) +
    (
    convert(int, substring(@page_num, 3, 1)) *power(2, 16)) +
    (
    convert(int, substring(@page_num, 2, 1)) *power(2, 8)) +
    (
    convert(int, substring(@page_num, 1, 1)))) )
    END;
    SELECT dbo.convert_page_nums(0xEE0000000100);

    结果为1:238

    警告:first_page列并不一直是指向表的第一页。毕竟这是一个未公开的命令。

    第二种获取页实际数字的方式是使用另外一个未公开的命令DBCC IND。例如:

    DBCC IND(testdb, fixed, -1);

    得到如下类似结果:

    PageFID PagePID IAMFID IAMPID ObjectID IndexID PartitionNumber PartitionID iam_chain_type PageType IndexLevel NextPageFID NextPagePID PrevPageFID PrevPagePID
      1238123910295787060172057594041925632 In-row data 100000

    第三种方式是使用一个未公开的function:sys.fn_PhysLocFormatter

    SELECT sys.fn_PhysLocFormatter (%%physloc%%) AS RID, *FROM Fixed;

    结果:
    RID    Col1    Col2    Col3    Col4
    (1:60928:0)    ABCDE    123    NULL    CCCC 
    请注意这个结果有所不同。

    下面将分别介绍五种类型的存储方式:

    一、固定长度的行;二、可变长度的行;三、Null和可变长度列;四、时间和日期数据;五、SQL_variant 数据

    首先,我们来看第一种:固定长度的行的存储。

    我们以前面创建的Fixed表为例:

    一旦表被创建,我们可以从目录视图中查看到相关列的信息;

    SELECTobject_id, type_desc,
    indexproperty(object_id, name, 'minlen') as min_row_len
    FROM sys.indexes whereobject_id=object_id('Fixed');

    SELECT column_id, name, system_type_id, max_length as max_col_len
    FROM sys.columns
    WHEREobject_id=object_id('Fixed');

    结果:

    object_id type_desc min_row_len
    1029578706 HEAP 22

    column_id name system_type_id max_col_len
    1 Col1 1755
    2 Col2 564
    3 Col3 1753
    4 Col4 1756

    注意:sysindexes目录视图包含列minlen和xmaxlen,存储了行的最小和最大长度。在Sql Server2008中,这些值在任何视图中是不可用的,除非你通过一个未公开的function:indexproperty读取它。对于一个只包含固定长度的列的表来说,indexproperty函数通过传入的minlen返回值等于列长度的总和(从sys.columns.max_length)加上4个字节。它不包含列数目的两个字节和用于null位图的字节。

    通过以下语句可以查看列的偏移量:

    SELECT c.name AS column_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('fixed');
    Col1 151754
    Col2
    24569
    Col3
    3317513
    Col4
    4617516

    邀月工作室

    对了,如何显示Buffer数据,请参看上篇内容
    简要说明:

    1、第一个字节:状态位A是0x10显示bit4打开,bit5未打开。我们得知该行没有可变长度列。

    2、第二个字节未使用。

    3、第三和第四字节是0x16等于22,显示了固定长度的列长度之和。

    4、各列的偏移量分别为4,9,13,16。

    5、第22字节处是0400,表明列数为4

    6、null bitmap未使用。

    说实话,这节和下节是本书第二难理解的内容。最难理解的内容要数第七章了。呵呵。邀月确实有点半生不熟。共同学习是我的目的。

    邀月注:本文版权由邀月和博客园共同所有,转载请注明出处。
    助人等于自助!  3w@live.cn
  • 相关阅读:
    java文件压缩与解压
    常见Java库漏洞汇总
    ref:Spring JDBC框架
    ref:web 防止SQL注入方法
    ref:spring配置数据库方式
    ref:web security最新学习资料收集
    Hack12306
    mysql copy data from table to another
    MYSQL
    tcpdump 抓包过滤
  • 原文地址:https://www.cnblogs.com/downmoon/p/1660642.html
Copyright © 2020-2023  润新知