TinyInt의 SQL Server 저장


12

SQL Server에서 왜 tinyint가 9B 행에 저장되어 있습니까? 어떤 이유로 NULL 비트 맵 마스크의 끝에 1 바이트가 더있는 것 같습니다.

    tempdb 사용;
    가다

    테이블 작성 tbl
    (
        TINYINT NOT NULL
    );
    가다

    tbl에 삽입 (i)
        값 (1);
    가다

    DBCC IND ( 'tempdb', 'tbl',-1);
    가다

    DBCC TRACEON (3604); -페이지 덤프가 콘솔로 이동합니다
    가다

    DBCC 페이지 ( 'tempdb', 1,168,3);
    가다

결과 (DBCC PAGE의 최하위 바이트가 먼저 표시되어 바이트를 반전 시켰습니다).

Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count = 0x0001 = 2B
NULL Bitmap = 0x0000 = 2B (what!?)

1
이것은 단지 교육입니까? 나는 필요한 경우 공간을 다듬기 위해 노력하고 있지만 이것은 아마도 내가 걱정할 1 바이트가 아닐 것이다.
Aaron Bertrand

이것은 교육적입니다. 다음 SQLSaturday 강의는 compressin에 관한 것입니다. 따라서 모든 데이터 유형에 대한 예제를 작성하여 사람들이 데이터 유형 선택의 의미를 이해하고 모든 데이터 유형에 대한 압축의 영향을 보여줍니다.
ooutwire

나는 tinyint가 7B의 오버 헤드와 함께 1B (즉)로 저장 될 것이라고 가정했다. 레코드 끝에 여분의 바이트가 무엇인지 궁금합니다. ??
ooutwire

TINYINT 열이 테이블의 유일한 열이 아닌 경우 다른 결과가 나옵니다 (결과가 예상과 일치하는지 확실하지는 않지만). 매우 드문 사용 사례처럼 보입니다.
Aaron Bertrand

분명히 유스 케이스의 일반적인 관심사는 아닙니다. 스토리지와 관련된 오버 헤드 비용을 모두 발생시키고 초보자가 페이지에서 열의 모양을 볼 수 있도록 각 데이터 유형을 단독으로 표시하려고했습니다. 여분의 바이트를 갖는 것이 이상하다고 생각합니다.
ooutwire

답변:


12

간단한 크기 추가를 사용하여 레코드를 계산하면 실제로 8 + 4 + 1 + 2 + 1 (헤더 + 고정 크기 + 널 비트 맵 수 + 널 비트 맵 자체)을 얻습니다. 그러나 힙 레코드는 전달 스텁 크기 ( 9 바이트) 보다 작을 수 없습니다. 레코드가 전달 스텁 으로 대체 될 수 있도록 보장 해야하기 때문입니다. 따라서 레코드는 실제로 9 바이트가됩니다. A smallint는 계산 및 최소 크기 모두 9 바이트입니다. 더 큰 것은 이미 전달 스텁보다 크므로 계산 크기가 레코드 크기와 일치합니다.


9 바이트도이 정의에 적용 CREATE TABLE tbl (i TINYINT NOT NULL PRIMARY KEY)되므로 힙의 일부인지 여부에 관계없이 모든 행에 대한 일반적인 규칙입니까?
Martin Smith

1
b- 트리는 힙 ( alter table ... drop constraint) 으로 변환 될 수 있으며 작업이 전체 재 구축이 아닙니다 (b- 트리 상단 페이지가 버리고 리프 페이지가 링크되지 않고 결과 힙임). 예약 논리가 여전히 적용됩니다. .
Remus Rusanu

나는이 레무스가 ... 주장했다 무엇을 증명 생각 improve.dk/archive/2011/06/07/...을
ooutwire

6

저자의 귀를 갖는 것이 좋습니다. :-) Kalen은 이것이 9의 어떤 것이 든 9로 채워지는 일종의 최소 행 길이의 집행이라고 생각합니다. 물론 이것이 가능한 경우는 거의 없습니다. VARCHAR (1) / CHAR (1)뿐만 아니라 TINYINT 및 BIT에 대한이 팬텀 바이트를 찾을 수 있습니다. SMALLINT 또는 CHAR (2)로 이동하면 9 이상으로 증가하지 않지만 CHAR (3)으로 이동하면 증가합니다.

따라서 기본적으로 데이터 유형을 현명하게 선택함으로써 얻을 수있는 효율성을 지적 할 수 있지만 스토리지 계층의 다른 요인으로 인해 규칙이 적용되지 않는 몇 가지 경우가 있습니다.

편집 더 구체적인 정보가 있기를 바랍니다. 이것이 바로 Internals 책의 저자가 생각하는 것임을 알려주고 싶었습니다. 그녀는 100 % 확실하지 않다.


Kalen에게 연락해 주셔서 감사합니다. 나는 지난 밤에 그 책을 파고 내 머리를 뽑고 있었다. 이것은 sql_variant에 대한 여분의 메타 데이터 바이트와 비슷합니다. 여기서는 팬텀 바이트 저장에 대해 설명 할 수있는 방법이 없습니다.
ooutwire

1
이 주석을 "이것은 극단적 인 경우입니다. 각 테이블에 단일 tinyint 또는 char (1)을 저장하도록 설계된 테이블이 많지 않기 때문입니다."
Aaron Bertrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.