SQL varchar 열 길이에 대한 모범 사례 [닫기]


290

새로운 SQL 테이블을 설정하거나 varchar기존 테이블에 새로운 열을 추가 할 때마다 한 가지 궁금합니다 length.

따라서 nametype 이라는 열이 있다고 가정 해 봅시다 varchar. 따라서 길이를 선택해야합니다. 나는 20자를 초과하는 이름을 생각할 수 없지만 결코 알 수는 없습니다. 그러나 20을 사용하는 대신 항상 다음 2 ^ n 수로 반올림합니다. 이 경우 길이를 32로 선택합니다. 컴퓨터 과학자의 관점에서 볼 때, 숫자 2 ^ n은 even다른 숫자보다 더 잘 보이기 때문에 아래 아키텍처가 다른 숫자보다 약간 더 잘 처리 할 수 ​​있다고 가정합니다.

반면에 MSSQL 서버는 varchar 열을 만들 때 기본 길이 값을 50으로 설정합니다. 그렇게 생각합니다. 왜 50? 그것은 임의의 숫자입니까, 아니면 평균 열 길이를 기준으로합니까?

MySQL, MSSQL, Postgres 등과 같은 다른 SQL Server 구현은 서로 다른 최상의 열 길이 값을 가질 수도 있습니다.

답변:


238

a를합니다 어떤 "최적화"가 없음 DBMS 알아요 VARCHARA의 2^n길이가 더 잘보다 수행 max이의 힘없는 길이.

초기 SQL Server 버전은 실제로 VARCHAR길이가 255 인 최대 길이가 더 높은 것을 처리했다고 생각 합니다. 이것이 여전히 사실인지 모르겠습니다.

거의 모든 DBMS에서 필요한 실제 스토리지는 max사용자가 정의한 길이 가 아니라 입력 한 문자 수에 따라 결정됩니다 . 따라서 저장 관점 (및 아마도 성능 측면에서도)에서 열을 VARCHAR(100)또는 로 선언하든 아무런 차이가 없습니다 VARCHAR(500).

당신은 볼 수 maxA의 제공 길이 VARCHAR제약 (또는 비즈니스 규칙)의 일종으로 열보다는 기술적 / 물리적 인 일을.

PostgreSQL의 경우 최상의 설정은 text길이 제한없이 사용 하는 CHECK CONSTRAINT것이며 비즈니스 수에 따라 문자 수를 제한합니다.

해당 요구 사항이 변경되면 테이블을 다시 작성할 필요가 없으므로 검사 제한 조건을 변경하는 것이 테이블을 변경하는 것보다 훨씬 빠릅니다.

같은 오라클과 다른 사람을 위해 적용 할 수 있습니다 - 오라클는 것 VARCHAR(4000)대신 text하지만.

VARCHAR(max)예를 들어 VARCHAR(500)SQL Server 간에 물리적 스토리지 차이가 ​​있는지 모르겠습니다 . 그러나 varchar(max)와 비교할 때 성능에 영향을 미칩니다 varchar(8000).

이 링크 참조 (Erwin Brandstetter의 코멘트로 게시)

편집 2013-09-22

bigown의 의견에 관하여 :

9.2 이전의 Postgres 버전 (초기 답변을 작성할 때 사용할 수 없었 습니다)에서 열 정의를 변경 하면 전체 테이블 다시 작성되었습니다 (예 : here 참조) . 9.2부터는 더 이상 그렇지 않으며 빠른 테스트를 통해 120 만 행이있는 테이블의 열 크기를 늘리는 데 실제로 0.5 초 밖에 걸리지 않음을 확인했습니다.

Oracle의 경우 큰 테이블의 varchar열 을 변경하는 데 걸리는 시간으로 판단하면 마찬가지 입니다. 그러나 나는 그것에 대한 어떤 언급도 찾을 수 없었다.

MySQL의 경우 매뉴얼에 " 대부분의 경우 ALTER TABLE원본 테이블의 임시 복사본을 만듭니다 "라고 표시됩니다. 그리고 내 자신의 테스트 ALTER TABLE는 열 크기를 늘리기 위해 120 만 행 (Postgres의 테스트와 동일)이있는 테이블에서 실행하는 데 1.5 분이 걸렸습니다. 그러나 MySQL에서는 "해결 방법"을 사용하여 검사 제약 조건을 사용하여 열의 문자 수를 제한 할 수 없습니다 .

SQL Server의 경우 이것에 대한 명확한 진술을 찾을 수 없었지만 varchar열 크기를 늘리는 실행 시간 (위에서 120 만 행 테이블 이상)은 다시 쓰기가 발생 하지 않음을 나타냅니다 .

2017-01-24 수정

SQL Server에 대해 (적어도 부분적으로) 잘못된 것 같습니다. 선언 된 길이 또는 열의 길이가 성능에 큰 차이가 있음을 보여주는 Aaron Bertrand의 답변을 참조하십시오 .nvarcharvarchar


34
실제로 이러한 열에 1자를 입력하더라도 VARCHAR (255)와 VARCHAR (500)에는 차이가 있습니다. 행의 끝에 추가되는 값은 저장된 데이터의 실제 길이를 저장하는 정수입니다. VARCHAR (255)의 경우 1 바이트 정수입니다. VARCHAR (500)의 경우 2 바이트입니다. 약간의 차이가 있지만 알고 있어야합니다. 성능에 어떤 영향을 줄 수 있는지에 대한 데이터는 없지만 조사 할 가치가 없을 정도로 작습니다.
NB

1
@NB : 이것이 SQL Server의 "마법"255 값에 대해 언급 한 것입니다. 설명해 주셔서 감사합니다.
a_horse_with_no_name

4
@NB 어떤 RDBMS를 언급하고 있습니까? SQL Server? 성능에 영향을 미칩니다. [N] VARCHAR (max)는 [N] VARCHAR (n)보다 약간 느리게 수행됩니다. 나는 최근 에이 사이트를 언급했다 . 내가 아는 모든 것에 대해 PostgreSQL도 마찬가지입니다.
Erwin Brandstetter

@ ErwinBrandstetter : 링크 주셔서 감사합니다. 같은 외모는 varchar(max)아마 오라클처럼CLOB
a_horse_with_no_name

1
varchar 길이 변경은 테이블을 다시 쓰지 않습니다. CHECK CONSTRAINT와 정확히 동일하게 전체 테이블에 대한 제약 조건 길이를 확인합니다. 길이를 늘리면 수행 할 작업이 없으면 다음 삽입 또는 업데이트 만 더 큰 길이를 허용합니다. 길이를 줄이고 모든 행이 새로운 작은 구속 조건을 통과하면 Pg는 다음 삽입 또는 업데이트가 새 길이 만 쓸 수 있도록하는 것 외에 추가 조치를 취하지 않습니다.
Maniero

70

VARCHAR(255)그리고 VARCHAR(2)걸릴 정확히 디스크에 동일한 양의 공간을! 따라서 제한해야 할 유일한 이유는 더 작아야 할 필요가 있기 때문입니다. 그렇지 않으면 모두 255로 만듭니다.

특히 정렬을 수행 할 때 더 큰 열은 더 많은 공간을 차지하므로 성능이 저하되면 걱정할 필요가 없으며 더 작아야합니다. 그러나 해당 테이블에서 하나의 행만 선택하면 모두 255 개만 만들 수 있습니다.

MySQL에 대한 최적의 varchar 크기는 무엇입니까?를 참조하십시오.


7
왜 그들을 모두 만들지 VARCHAR(MAX)않습니까? 데이터베이스를 모델링 할 때 공간 만 고려하는 것은 아닙니다. 모델링중인 도메인이 데이터 유형과 크기를 주도해야합니다.
오디드

6
@Oded VARCHAR(MAX)varchar(255)or 와 같지 않습니다. varchar(65535)-varchar max는 text데이터 유형입니다. 그리고 당신의 요점으로-그가 "도메인이 무엇을 모델링하고 있는지"를 안다면 그는이 질문을하지 않을 것입니다. 분명히 그는 자신의 데이터가 얼마나 큰지 알지 못하며, 전체 크기로 만들면 아무것도 해치지 않는다고 안심시킵니다.
Ariel

4
@Ariel : 고려해야 할 인덱스에는 문제와 제한이 있습니다. (a,b,c,d)네 개의 열이 모두 인 경우 색인을 가질 수 없습니다 VARCHAR(255).
ypercubeᵀᴹ

@ypercube 사실, 열에 색인이 필요한 경우 크기에 더주의를 기울여야합니다. 그러나 대부분의 열에는 인덱스가 필요하지 않으므로 대부분 걱정할 필요가 없습니다.
Ariel

정확한 값을 알고 있으면 char을 사용하는 것이 좋습니다. 한편 여전히 정확한 경우 varchar를 사용하고 동적 메모리 할당이므로 255를 유지하므로 크기에 대해 걱정할 필요가 없습니다.
Faris Rayhan

54

새 SQL 테이블을 설정할 때마다 2 ^ n이 "짝수"가되는 것과 같은 방식으로 생각하지만 여기에 답을 요약하면 varchar (2 ^ n)을 정의하여 스토리지 공간에 큰 영향을 미치지 않습니다. 또는 심지어 varchar (MAX).

즉, 높은 varchar () 제한을 설정할 때 스토리지 및 성능에 대한 잠재적 영향을 여전히 예상해야합니다. 예를 들어, 전체 텍스트 인덱싱으로 제품 설명을 보유 할 varchar (MAX) 열을 작성한다고 가정 해 보겠습니다. 설명의 99 %가 500 자에 불과한 경우 갑자기 해당 설명을 Wikipedia 기사로 바꾸는 사람이 있으면 예상치 못한 스토리지 및 성능 저하가 발생할 수 있습니다.

Bill Karwin에서 고려해야 할 또 다른 사항 :

가능한 성능 영향은 MySQL에 있습니다. MySQL에서 임시 테이블 및 MEMORY 테이블은 VARCHAR 열을 고정 길이 열로 저장하고 최대 길이까지 채 웁니다. VARCHAR 열을 필요한 최대 크기보다 훨씬 크게 디자인하면 필요한 것보다 많은 메모리를 사용하게됩니다. 캐시 효율성, 정렬 속도 등에 영향을줍니다.

기본적으로 합리적인 비즈니스 제약과 약간 더 큰 크기의 오류가 있습니다. @oneday가 지적한 것처럼 영국의 가족 이름은 일반적으로 1-35 자 사이입니다. varchar (64)로 결정하면 최대 666 자라고 하는 이 사람의 가족 이름 을 저장하지 않는 한 아무 것도 아프지 않을 것 입니다. 이 경우 varchar (1028)가 더 의미가있을 수 있습니다.

그리고 도움이되는 경우 varchar 2 ^ 5에서 2 ^ 10이 채워지면 다음과 같이 보일 수 있습니다.

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit

31

가장 좋은 값은 기본 도메인에 정의 된대로 데이터에 적합한 값입니다.

일부 도메인의 VARCHAR(10)경우 Name속성에 적합하며 다른 도메인의 VARCHAR(255)경우 최선의 선택 일 수 있습니다.


15

a_horse_with_no_name의 답변에 추가하면 다음과 같은 관심을 가질 수 있습니다 ...

VARCHAR (100) 또는 VACHAR (500)로 열을 선언하든 아무런 차이가 없습니다.

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

길이 바이트와 널 입력 가능 바이트를 잊지 마십시오.

name varchar(100) not null 1 바이트 (길이) + 최대 100 자 (latin1)입니다.

name varchar(500) not null 2 바이트 (길이) + 최대 500 자 (latin1)입니다.

name varchar(65533) not null 2 바이트 (길이) + 최대 65533 자 (latin1)입니다.

name varchar(65532) 2 바이트 (길이) + 최대 65532 자 (latin1) + 1 바이트 바이트입니다.

도움이 되었기를 바랍니다 :)


당신은 MySQL을 사용하고 있으며, 질문은 MSSQL에 관한 것입니다
보그 마트

6

항상 비즈니스 도메인 전문가에게 문의하십시오. 그것이 당신이라면, 산업 표준을 찾으십시오. 예를 들어 문제의 도메인이 자연인의 가족 이름 (성) 인 경우 영국 비즈니스의 경우 개인 정보 를 위해 영국 Govtalk 데이터 표준 카탈로그 로 이동하여 가족 이름이 1 ~ 35 자 사이임을 알게됩니다 .


3

최근에 이것을 확인하지는 않았지만 과거에는 Oracle과 함께 JDBC 드라이버가 쿼리 실행 중에 결과 집합을 다시 유지하기 위해 메모리 덩어리를 예약한다는 것을 알고 있습니다. 메모리 청크의 크기는 열 정의 및 페치 크기에 따라 다릅니다. 따라서 varchar2 열의 길이는 예약 된 메모리 양에 영향을줍니다. 우리는 항상 varchar2 (4000) (당시 최대 값)를 사용하고 가비지 수집이 오늘날보다 훨씬 덜 효율적이므로 몇 년 전 심각한 성능 문제가 발생했습니다.


-2

어떤 의미에서는 2 ^ 8 자보다 작은 문자는 여전히 데이터 바이트로 등록됩니다.

VARCHAR <255를 사용하여 동일한 양의 공간을 소비하는 것으로 남겨진 기본 문자를 설명하는 경우.

255는 특히 과도한 입력을 줄이려는 경우가 아니라면 좋은 기준선 정의입니다.


" 2 ^ 8 자 미만의 문자는 여전히 데이터 바이트로 등록되지만 "-잘못되었습니다. 데이터베이스는 VARCHAR 유형으로 제공된 수의 문자 만 저장합니다. 열을 선언 할 때 "등록", 예약 또는 초기화 된 공간이 없습니다 .
a_horse_with_no_name
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.