none
数据记录的长度问题和Record Attributes的意思 RRS feed

  • 问题

  • 使用下面的sql语句建立环境

    USE [pratice]
    GO
    
    --DROP TABLE testnullvarchar
    --DROP TABLE testnullchar
    --DROP TABLE testnotnullvarchar
    --DROP TABLE testnotnullchar
    
    --允许空,varchar类型
    CREATE TABLE testnullvarchar(id INT ,NAME VARCHAR(20) NULL)
    GO
    --允许空,char类型
    CREATE TABLE testnullchar(id INT,NAME CHAR(20) NULL)
    GO
    --不允许空,varchar类型
    CREATE TABLE testnotnullvarchar(id INT ,NAME VARCHAR(20) NOT NULL)
    GO
    --不允许空,char类型
    CREATE TABLE testnotnullchar(id INT ,NAME CHAR(20) NOT NULL)
    GO
    
    --插入数据
    INSERT INTO [dbo].[testnullvarchar] ( [id] )
    SELECT 1
    GO
    
    INSERT INTO [dbo].[testnullchar] ( [id] )
    SELECT 1
    GO
    
    INSERT INTO [dbo].[testnotnullchar] ( [id],[NAME] )
    SELECT 1,''
    GO
    
    INSERT INTO [dbo].[testnotnullvarchar] ( [id],[NAME] )
    SELECT 1,''
    GO
    
    SELECT * FROM testnullvarchar
    SELECT * FROM testnullchar
    SELECT * FROM testnotnullvarchar
    SELECT * FROM testnotnullvarchar
    
    
    CREATE TABLE DBCCResult (
    PageFID NVARCHAR(200),
    PagePID NVARCHAR(200),
    IAMFID NVARCHAR(200),
    IAMPID NVARCHAR(200),
    ObjectID NVARCHAR(200),
    IndexID NVARCHAR(200),
    PartitionNumber NVARCHAR(200),
    PartitionID NVARCHAR(200),
    iam_chain_type NVARCHAR(200),
    PageType NVARCHAR(200),
    IndexLevel NVARCHAR(200),
    NextPageFID NVARCHAR(200),
    NextPagePID NVARCHAR(200),
    PrevPageFID NVARCHAR(200),
    PrevPagePID NVARCHAR(200)
    )
    GO

    --TRUNCATE TABLE DBCCResult
    INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,testnullvarchar,-1) ')
    
    SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 
    
    
    DBCC TRACEON(3604,-1)
    GO
    DBCC PAGE([pratice],1,126,3)
    GO
    
    EXEC [sys].[sp_spaceused] @objname = N'testnullvarchar', -- nvarchar(776)
        @updateusage = 'true' -- varchar(5)
        
    SELECT LEN(name) FROM testnullvarchar WHERE [id]=1
    
    ------------------------------------------------------
    --TRUNCATE TABLE DBCCResult
    INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,testnullchar,-1) ')
    
    SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 
    
    
    DBCC TRACEON(3604,-1)
    GO
    DBCC PAGE([pratice],1,8370,3)
    GO
    
    EXEC [sys].[sp_spaceused] @objname = N'testnullchar', -- nvarchar(776)
        @updateusage = 'true' -- varchar(5)
    
    SELECT LEN(name) FROM testnullchar WHERE [id]=1
    
    --------------------------------------------------------
    --TRUNCATE TABLE DBCCResult
    INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,testnotnullvarchar,-1) ')
    
    SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 
    
    
    DBCC TRACEON(3604,-1)
    GO
    DBCC PAGE([pratice],1,8354,3)
    GO
    
    EXEC [sys].[sp_spaceused] @objname = N'testnotnullvarchar', -- nvarchar(776)
        @updateusage = 'true' -- varchar(5)
        
    SELECT LEN(name) FROM testnotnullvarchar WHERE [id]=1
    
    --------------------------------------------------------
    --TRUNCATE TABLE DBCCResult
    INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,testnotnullchar,-1) ')
    
    SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 
    
    
    DBCC TRACEON(3604,-1)
    GO
    DBCC PAGE([pratice],1,37266,3)
    GO
    
    EXEC [sys].[sp_spaceused] @objname = N'testnotnullchar', -- nvarchar(776)
        @updateusage = 'true' -- varchar(5)
    
    SELECT LEN(name) FROM testnotnullchar WHERE [id]=1

    看每张表的数据页的时候有疑问

    testnullvarchar表

    记录属性NULL_BITMAP是什么意思?

    ----------------------------------------------------------

    testnullchar表

    2013年9月13日 11:45

答案

  • For testnullchar and testnotnullchar:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    20 bytes for char(20) (2nd column)

    Total 31 bytes.


    • 已编辑 rmiao 2013年9月13日 14:44
    • 已标记为答案 Steven.桦仔 2013年9月14日 6:13
    2013年9月13日 14:38
  • For testnullvarchar and testnotnullvarchar:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    Total 11 bytes.


    • 已编辑 rmiao 2013年9月13日 14:43
    • 已标记为答案 Steven.桦仔 2013年9月14日 6:13
    2013年9月13日 14:38
  • If you put same value ( say 'test') in name column in testnullvarchar or testnotnullvarchar, length will be 19:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    2 bytes for number of variable length columns in the table

    2 bytes for name column offset

    4 bytes for name (test)


    2013年9月13日 14:43

全部回复

  • testnotnullvarchar表

    testnotnullchar表

    2013年9月13日 11:48
  • For testnullchar and testnotnullchar:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    20 bytes for char(20) (2nd column)

    Total 31 bytes.


    • 已编辑 rmiao 2013年9月13日 14:44
    • 已标记为答案 Steven.桦仔 2013年9月14日 6:13
    2013年9月13日 14:38
  • For testnullvarchar and testnotnullvarchar:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    Total 11 bytes.


    • 已编辑 rmiao 2013年9月13日 14:43
    • 已标记为答案 Steven.桦仔 2013年9月14日 6:13
    2013年9月13日 14:38
  • If you put same value ( say 'test') in name column in testnullvarchar or testnotnullvarchar, length will be 19:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    2 bytes for number of variable length columns in the table

    2 bytes for name column offset

    4 bytes for name (test)


    2013年9月13日 14:43
  • 谢谢rmiao大侠

    那么Record Attribute=nNULL_BITMAP 与 Record Attribute= NULL_BITMAP VARIABLE_COLUMNS

    有什么区别吗?

    2013年9月13日 14:43
  • Null_bitmap in record attributes means this record contains null_bitmap field. Likewise, 'null_bitmap variable_columns' means this record contains null_bitmap field with variable length columns.
    2013年9月13日 14:59
  • Null_bitmap in record attributes means this record contains null_bitmap field. Likewise, 'null_bitmap variable_columns' means this record contains null_bitmap field with variable length columns.

    在请问这个null_bitmap 段有什么用的?

    为什麽要有1 byte for null bitmap

    还有

    2 bytes for length of fixed length columns用来统计字段的长度,len()函数也是读取这个地方

    那么2 bytes for number of columns in the table有什么用?

    2013年9月13日 15:09
  • 2 bytes for number of variable length columns in the table

    2 bytes for name column offset

    4 bytes for name (test)

    rmiao大侠能解释一下吗?

    2013年9月13日 15:10
  • 我继续插入第二行记录

    --插入数据
    INSERT INTO [dbo].[testnullvarchar] ( [id],[NAME] )
    SELECT 2,'你'
    GO
    
    INSERT INTO [dbo].[testnullchar] ( [id],[NAME] )
    SELECT 2,'你'
    GO
    
    INSERT INTO [dbo].[testnotnullchar] ( [id],[NAME] )
    SELECT 2,'你'
    GO
    
    INSERT INTO [dbo].[testnotnullvarchar] ( [id],[NAME] )
    SELECT 2,'你'
    GO

    testnullvarchar表:
    Slot 1 Offset 0x6b Length 17

    Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

    Memory Dump @0x0A44C06B

    00000000:   30000800 02000000 0200fc01 001100c4 †0...............         
    00000010:   e3†††††††††††††††††††††††††††††††††††.                        

    Slot 1 Column 0 Offset 0x4 Length 4

    id = 2                               

    Slot 1 Column 1 Offset 0xf Length 2

    NAME = 你   

    ------------------------------------------------------------

    testnullchar表

    Slot 1 Offset 0x7f Length 31

    Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
    Memory Dump @0x0921C07F

    00000000:   10001c00 02000000 c4e32020 20202020 †..........               
    00000010:   20202020 20202020 20202020 0200fc††††            ...          

    Slot 1 Column 0 Offset 0x4 Length 4

    id = 2                               

    Slot 1 Column 1 Offset 0x8 Length 20

    NAME = 你  

    ---------------------------------------------------------------

    testnotnullvarchar表

    Slot 1 Offset 0x6b Length 17

    Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

    Memory Dump @0x0921C06B

    00000000:   30000800 02000000 0200fc01 001100c4 †0...............         
    00000010:   e3†††††††††††††††††††††††††††††††††††.                        

    Slot 1 Column 0 Offset 0x4 Length 4

    id = 2                               

    Slot 1 Column 1 Offset 0xf Length 2

    NAME = 你                            

    -------------------------------------------------------------------------

    testnotnullchar表

    Slot 1 Offset 0x7f Length 31

    Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
    Memory Dump @0x0A44C07F

    00000000:   10001c00 02000000 c4e32020 20202020 †..........               
    00000010:   20202020 20202020 20202020 0200fc††††            ...          

    Slot 1 Column 0 Offset 0x4 Length 4

    id = 2                               

    Slot 1 Column 1 Offset 0x8 Length 20

    NAME = 你  

    2013年9月13日 15:16
  • If you put same value ( say 'test') in name column in testnullvarchar or testnotnullvarchar, length will be 19:

    2 bytes row header

    2 bytes for length of fixed length columns

    4 bytes for int (1st column)

    2 bytes for number of columns in the table

    1 byte for null bitmap

    2 bytes for number of variable length columns in the table

    2 bytes for name column offset

    4 bytes for name (test)


    按照rmiao大侠你的公式

    testnotnullvarchar表

    Slot 1 Offset 0x6b Length 17

    长度为17是没有错的

    2 bytes for name column offset两个字节的位移怎麽得出来的?

    Slot 1 Column 0 Offset 0x4 Length 4

    id = 2                               

    Slot 1 Column 1 Offset 0xf Length 2

    Oxf-Ox4=12 怎麽得出两个字节??


    2013年9月13日 15:23
  • Every variable length column with value has 2 bytes offset, it's by design.

    2013年9月13日 15:31
  • Null_bitmap in record attributes means this record contains null_bitmap field. Likewise, 'null_bitmap variable_columns' means this record contains null_bitmap field with variable length columns.

    在请问这个null_bitmap 段有什么用的?

    为什麽要有1 byte for null bitmap

    还有

    2 bytes for length of fixed length columns用来统计字段的长度,len()函数也是读取这个地方

    那么2 bytes for number of columns in the table有什么用?

    Those are used by sql internally, you don't need them.
    2013年9月13日 15:33
  • 2 bytes for number of variable length columns in the table - how many variable length columns in the table

    2 bytes for name column offset - column 'name' is varchar, needs 2 bytes offset 

    4 bytes for name (test) - for value 'test' in name column

    rmiao大侠能解释一下吗?


    2013年9月13日 15:35
  • http://www.ujaska24.pl Polecam pokoje gościnne u Jaśka Ząb koło Zakopanego
    2013年9月13日 17:17
  • 根据这张表我知道是什么意思了

    2013年9月14日 5:47