연구개발/DBA

테이블의 행 구조

HEAD1TON 2012. 1. 16. 01:09
/*
테이블의 행 구조
Status Bit A / B (1 + 1 byte)
고정 컬럼 길이 (2)
고정길이 데이터(n)
컬럼 수(2)
null bitmap (컬럼마다 1bit)

가변 컬럼 수(2)
컬럼 오프셋(2 * 가변길이)
가변 컬럼 데이터(n)


Header        Fixed Data        컬럼수        NB        VB        Variable Data
                                                        Null
                                                        Block
                                                                    Variable
                                                                    Block
*/


/* 고정 컬럼 테이블 */
USE tempdb;
GO
IF OBJECT_ID('Fixed') IS NOT NULL
    DROP TABLE Fixed
GO
CREATE TABLE Fixed
(
    Col1        CHAR(5)    NOT NULL
    ,Col2    INT            NOT NULL
    ,Col3    CHAR(3)    NULL
    ,Col4    CHAR(6)    NOT NULL
    ,Col5    FLOAT        NOT NULL
)

SELECT * FROM sysindexes
WHERE id = OBJECT_ID('fixed');
--0x790000000100
SELECT * FROM syscolumns
WHERE id = OBJECT_ID('fixed');

INSERT Fixed VALUES ('abcde', 1, NULL, 'aaaa', 12.3);

SELECT * FROM Fixed;

SELECT CONVERT(INT, 0x79);
--121
DBCC TRACEON(3604);
DBCC PAGE(tempdb, 1, 121, 3);
DBCC TRACEOFF(3604);

--0000000000000000:   10001e00 61626364 65    010000 00    000000 †....abcde.......
--                                    4바이트 헤더  a  b c   d   e       Col2(4바이트)   NULL(3바이트)
--0000000000000010:   61616161 2020        9a99 99999999 2840    0500 †aaaa  ......(@..
--                                     a  a  a  a  빈칸두개            Col5                        컬럼 5개
--0000000000000020:   04†††††††††††††††††††††††††††††††††††.               
--                                    NULL이 몇번째 컬럼에 있느냐 - 00100(아래 참고)
    --Col1        CHAR(5)    NOT NULL  (0)
    --,Col2    INT            NOT NULL         (0)
    --,Col3    CHAR(3)    NULL                 (1)
    --,Col4    CHAR(6)    NOT NULL         (0)
    --,Col5    FLOAT        NOT NULL         (0)
--00100 =  2*0(4) + 2*0(3) + 2*2(2) + 2*0(1) + 2*0(0)


/* 가변컬럼 테이블 */
USE tempdb;
GO
IF OBJECT_ID('variable') IS NOT NULL
    DROP TABLE variable
GO
CREATE TABLE variable
(
    Col1        CHAR(3)            NOT NULL
    ,Col2    VARCHAR(250)    NOT NULL
    ,Col3    VARCHAR(5)        NULL
    ,Col4    VARCHAR(20)    NOT NULL
    ,Col5    SMALLINT            NOT NULL
);
GO

SELECT * FROM sysindexes
WHERE id = OBJECT_ID('variable');
--0x7F0000000100
SELECT * FROM syscolumns
WHERE id = OBJECT_ID('variable');

INSERT variable VALUES ('abc', replicate('x', 250), NULL, 'abc', 123);

SELECT * FROM variable;
GO

DBCC TRACEON(3604);
DBCC PAGE(tempdb, 1, 127, 3);
SELECT CONVERT(INT, 0x7F);
DBCC TRACEOFF(3604);
                                                                                                --가변컬럼이 3개(2바이트)
                                                                            -- 컬럼개수 5개(2바이트)
--0000000000000000:   30000900 616263        7b 00    0500    04 0300    0e01    †0.    .abc{........
                                                                                                                -- Col2주소
--                                    헤더4바이트    a  b   c    smallint2바이트     널비트 1바이트(00100)
--0000000000000010:   0e01        1101       78787878 78787878 78787878 †....xxxxxxxxxxxx
                                -- Col3주소     Col4주소        --값
--                0e01위에 있는 주소와 0e01 밑에 있는 주소가 같은 이유는 가변컬럼이기때문에 이 주소에서 시작한다.
--                왜냐면 Col3가 null값이기에 값이 없으므로 같은 주소에서 시작하는 것.
--0000000000000020:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000030:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000040:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000050:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000060:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000070:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000080:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000090:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000A0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000B0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000C0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000D0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000E0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--00000000000000F0:   78787878 78787878 78787878 78787878 †xxxxxxxxxxxxxxxx
--0000000000000100:   78787878 78787878 78787878 78786162 †xxxxxxxxxxxxxxab
--                                                                                                a  b
--0000000000000110:   63†††††††††††††††††††††††††††††††††††c               
--                                      c