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

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

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

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

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



답변

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


답변

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

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

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


답변

새 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


답변

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

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


답변

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 바이트 바이트입니다.

도움이 되었기를 바랍니다 🙂


답변

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


답변

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