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.