INT보다 TINYINT를 언제 사용해야합니까?


91

일반적으로 항상 Ints를 사용합니다. 나는 당신이 있기 때문에 이론적으로이하지만, 가장 좋은 방법이 아닙니다 알고 있어야 데이터를 저장하기 위해 보장 할 가장 작은 데이터 형식을 사용합니다.

예를 들어, tinyint저장할 유일한 데이터가 1, 0 또는 null이라는 것을 알 때 사용하는 것이 좋습니다 (나중에 2 또는 3으로 확장 할 가능성이 매우 적음).

그러나이 작업을 수행하는 유일한 이유는 저장 목적으로 4 바이트 대신 1 바이트를 사용하는 것입니다.

하드 드라이브의 공간을 절약하는 것 외에 다른 용도로 사용하는 경우 tinyint(또는 smallint심지어 bigint) 영향은 무엇입니까 int?


2
이것은 매우 좋은 질문입니다 (+1). MySQL에는 SELECT ... PROCEDURE ANALYSE ()가 있는데, 이는 주어진 SELECT에 대해 테이블이 가지고있는 가장 작은 데이터 형식을 실제로 권장합니다. 그것은 부분적으로 내 대답의 영감이었습니다.
RolandoMySQLDBA

3
좋은 질문이지만 정밀한 범위는 0-255입니다. 비트 필드는 0 또는 1 (또는 NULL)입니다. tinyint의 저장 비용은 1 바이트입니다. 테이블의 8 비트 필드마다 1 바이트의 스토리지 비용이 발생합니다. msdn.microsoft.com/ko-kr/library/ms187745.aspxmsdn.microsoft.com/ko-kr/library/ms177603.aspx
billinkc

@billinkc 맞아. 그렇기 때문에 2 또는 3을 포함하도록 열을 확장 할 수 있다고 언급 한 이유입니다. 2 또는 3을 포함하는 경우 tinyint (가장 작은 규모)를 사용해야합니다.
Richard

1
"예를 들어, 저장할 유일한 데이터가 1, 0 또는 null이라는 것을 알 때 tinyint를 사용하는 것이 좋습니다 (나중에 2 또는 3으로 확장 할 가능성이 매우 적음)." 그런 일에 ENUM을 사용합니다. 이들은 비트 필드로 저장되며 다른 많은 사람들이 지적했듯이 레코드 당 적은 비용 절감은 전체 데이터베이스에 비해 많은 비용을 절감합니다.

2
@ user6665 I'd use an ENUM for such a thing.SQL Server에는 없지만 어떤 종류의 열거 형도 없기 때문에 그렇지 않습니다.
underscore_d

답변:


92

디스크 공간이 저렴합니다. 요점이 아닙니다!

스토리지 공간 측면에서 생각하지 말고 대신 버퍼 풀과 스토리지 대역폭에 대해 생각하십시오 . 극단적으로 CPU 캐시와 메모리 버스 대역폭 . 링크 된 기사는 클러스터링 된 키 선택 (INT 대 GUID 대 순차 GUID)의 문제를 강조하는 시리즈의 일부이지만 바이트가 만들 수있는 차이를 강조합니다.

가장 중요한 메시지는 디자인 문제입니다. VLDB 영역에 도달 할 때까지 해당 스펙 서버의 개별 데이터베이스에 차이가 표시되지 않지만 몇 바이트를 절약 할 수있는 경우에는 그렇지 않습니다.

이전 질문 에서 설명한 환경을 생각 나게합니다 . SQL 인스턴스 당 크기가 50mb-50GB 인 400 개 이상의 데이터베이스 해당 환경에서 데이터베이스 당 레코드 당, 테이블 당 몇 바이트를 제거하면 상당한 차이가 생길 수 있습니다.


29

다른 답변 외에도 ...

행과 색인 항목은 8k 페이지에 저장됩니다. 따라서 행당 3 바이트의 백만 행은 디스크에서 3MB가 아닙니다. 이는 페이지 당 행 수 ( "페이지 밀도")에 영향을줍니다.

nvarchar-varchar, smalldatetime-datetime, int-tinyint 등에도 동일하게 적용됩니다.

편집, 2013 년 6 월

http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx

이 기사는

중요한 기준은 카디널리티 및 페이지 대 행 비율입니다.

따라서 데이터 유형의 선택은 중요합니다


5
좋은 지적. 최악의 최악의 예는 열을 추가하려는 완전히 고정 된 길이의 열로 구성된 4028 바이트 행입니다. smallint를 추가하면 4030 (페이지 당 2 행)이되지만 int는 경계를 넘게됩니다 (페이지 당 1 행, 페이지 당 4028 바이트 낭비).
Mark Storey-Smith

한 번은 int vs bigint에서 성능 테스트를 수행했습니다. 백만 개의 레코드를 저장하고 시간과 스토리지를 비교 한 후 하나씩 검색하여 성능을 다시 측정합니다. 나는 큰 차이점을 보지 못했다. int와 tinyint에 대해 동일한 성능 테스트를 수행합니다. 실제로 애플리케이션의 80 %에 대해서는 무시할 수있어보다 일관된 데이터 유형과 유지 보수 비용이 줄어 듭니다.
Saeed Neamati

1
@SaeedNeamati 당신은 할 수 있습니다 기사 다시 읽어 에서 마크의 대답 ( " - 나는 ...이 모든 시간을 듣고 ... 우리가 나중에 성능에 대해 걱정거야? 그냥이 작업이 완료하자 ... 당신이 들어 본 적이을 ")와 여기 GBN의의 . 집으로 가져가는 것은 비효율적 인 선택이 올바른 규모로 줄무늬를 보여줄 것이며 OP의 직감은 잘못이 아니라고 생각합니다.
ruffin

14

고려해야 할 것은 테이블 스토리지 만이 아닙니다. int 열이 복합 키의 일부인 색인을 사용하는 경우, 색인 페이지가 최대한 가득 차기를 원할 것입니다. 이는 색인 항목이 가능한 작은 결과입니다.

BTREE 페이지의 색인 항목을 검사하는 것이 작은 데이터 유형에서는 조금 더 빠를 것입니다. 그러나 인덱스 항목과 관련된 VARCHAR은 INT보다 TINYINT를 사용하여 성능 향상을 상쇄 (널리 화)합니다.

그럼에도 불구하고 인덱스 항목에 복합 항목이 있고 모두 정수인 경우 정수가 작을수록 바이트 단위가 작을수록 좋습니다.


13

데이터베이스가 커지면 모든 것이 복잡해집니다.

  • 유지 관리 기간을 확대하거나 일정을 조정해야합니다.
  • 백업 (종료 전체 백업은 터무니없는 시간이되므로 차등 또는 로그 백업이 필요하며 일주일에 한 번, 한 달에 한 번은 전체 백업을 수행해야 함)
  • 퍼포먼스 유지 관리는 시간을 낭비하는 사람이되고 (수백만 행 테이블에 인덱스를 생성하는 데 사소한 시간이 걸리지 않습니다), 테이블을 넓히면 일정을 조정해야하며 상황이 악화됩니다.
  • 네트워크를 통해 100Gb 백업을 전송하는 것은 케이크 조각이 아닙니다. 특히 네트워크 (알 수없는 이유로)가 75Gb 마크에 연결을 끊는 데 고집이 있다면 ... (설치로 인해 발생했습니다. 네트워크의 네트워크에 연결된 드라이브로 백업하는 중-네트워크) ...

그리고 어떤 데이터 유형이 그와 관련이 있습니까? 모두. 행 크기가 필요한 것보다 큰 행을 사용하면 행 크기가 페이지에 하나 이상의 레코드를 기록 할 수없는 경우 데이터베이스 페이지가 필요보다 꽉 차거나 공간을 낭비하게됩니다. 결과적으로 읽고 쓰는 데 더 많은 페이지가 필요하고 더 많은 RAM 메모리가 캐시에 사용됩니다 (더 큰 레코드는 더 큰 메모리가 필요함). 또한 데이터 유형이 디스크에서 필요로하는 것보다 더 크게 지정되기 때문에 인덱스는 동일한 문제를 겪게됩니다. 특히 생성 된 다른 인덱스가 해당 기본 키를 해당 정의에 암시 적으로 복사하기 때문에 2 개의 BIGINT 열 기본 키를 복합하는 경우 특히 그렇습니다.

수백만 행 또는 수백만 행으로 FK 된 작은 테이블이있는 테이블의 일부 열은 데이터를 저장하는 데 4 바이트 정수가 필요하지 않지만 2 바이트는 충분합니다 -SMALLINT를 사용하십시오 . 0-255 범위의 값이 충분하면 TINYINT 입니다. 예 / 아니요 플래그? 있다 BIT는 .


9

대한 동안 tinyintint디스크 공간, 페이지 분할 및 유지 보수 시간과 분명한 차이가 있으며, 이러한 중 하나를 없을 것이다 varchar.

varchar(4000)어쨌든 필요한 텍스트 만 사용하므로 모든 텍스트 필드를로 선언하지 마십시오 . 훨씬 더 당신은 당신의 데이터가 절대로 잘리지 않을 것이라고 보장 할 것입니다.

대답은 물론입니다.

  1. 의도의 설명 (이름 필드가 4000 자 여야하는 이유를 아무도 알 수 없으므로)
  2. 아무도 전기를 이름으로 입력하지 않도록 확인합니다.

이 같은 이유 tinyint도 마찬가지입니다.


3
이것은 오래된 스레드이지만 설명 및 유효성 검사가 유일한 이유는 아닙니다. VARCHAR (20)이어야하는 것에 대해 VARCHAR (4000)이있는 경우 조회 계획은 메모리 및 CPU 요구 사항이 해당 열과 관련하여 필요한 것의 많은 배수라고 생각합니다. 이 작업을 수행하는 데 시간이 걸리지 않았지만 VARCHAR (20)에 대한 쿼리 계획을보고 VARCHAR (4000)로 변경하고 예상 비용을 확인하여이 내용을 볼 수있을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.