2010년 12월 30일 목요일

CHAR vs VARCHAR ?



CHAR를 사용할지 VARCHAR를 사용할 지의 문제는
문자열 데이터의 타입을 선정할 때, 항상 고민하는 부분이 아닐까 생각된다.

CHAR VARCHAR의 장단점을 확인해보고, 그 장단점에 맞게 선택하는 것이 최적일 것이라 생각한다.

1. CHAR
  1.1 특징
    1.1.1 Disk에 저장 시, 고정 길이로 저장된다.
    1.1.2 고정 길이이기 때문에, 별도의 유효(실질) 데이터 길이를 관리하지 않는다.
  1.2 장점
    1.2.1 고정 길이이기 때문에, 이 컬럼의 변경으로 인해서 Record의 위치 이동(Row migration)이 필요한 경우는 없다.
    1.2.2 별도의 유효(실질) 데이터 길이를 관리하지 않기 때문에 VARCHAR에 비해서 최소 1~2 바이트는 절약된다.
  1.3 단점
    1.3.1 실제 데이터의 길이와 관계 없이 테이블 생성 시(CREATE TABLE...)에 정의된 사이즈만큼 Disk를 사용한다.


2. VARCHAR
  2.1 특징
    2.1.1 Disk에 저장 시, 가변 길이로 저장된다.
    2.1.2 가변 길이이기 때문에, 별도로 실제 데이터의 길이를 관리해야 한다. (데이터의 길이에 따라서 1~2바이트가 사용됨)
  2.2 장점
    2.2.1 실제 데이터의 길이 변화가 심해도 Disk 공간을 절약할 수 있다.
  2.3 단점
    2.3.1 이 컬럼의 값이 예전보다 긴 값으로 변경될 경우, Record의 위치 이동(Row migration)이 발생할 수 있다.
    2.3.2 실제 데이터의 길이 값을 관리해야 하기 때문에 1~2바이트가 더 필요하다.

여기서 참고로
Disk의 공간을 더 차지한다는 것은, 데이터 파일의 각 페이지 낭비가 커서 데이터 파일의 사이즈가 커지는 결과를 가져오고, 이는 큰 Disk가 필요하다는 것보다는 MySQL이 쿼리를 처리하기 위해서 읽어야 하는 Disk의 페이지 수가 많아진다는 것이 더 큰 영향이라고 볼 수 있다. (, 레코드 100건을 읽기 위해서 데이터 파일 사이즈가 작을 때에는 1 Disk 읽기로 완료되었던 작업이 파일 사이즈가 커져서 Disk 읽기 2번이 필요 해질 수 있다는 것을 의미한다.)







그럼, 이제 위의 내용을 기초로 어떤 데이터를 CHAR로 또는 VARCHAR 선택해야 할지 생각 해보자.
A. 컬럼의 모든 값의 길이가 동일한 경우
B. 1~2 글자의 Alpha-numeric
C. 거의 대부분이 15자리 Alpha-numeric 값인데 가끔 10~14 자리 값이 들어올 수 있는 경우

조금은 억지가 있는 질문들이지만

AB의 케이스 모두 일반적으로 CHAR로 설정하는 것이 좋지만,

B의 케이스는 UTF8 CHAR(1) 3바이트, EUCKR CHAR(1) 2바이트를 차지하게 되는데
저장되는 데이터가 Alpha-numeric이라면 조금씩의 낭비는 발생하게 되며
이를 피하기 위해서는 해당 컬럼만 CharacterSet을 별도로 지정 해주는 방법도 있지만 
상당한 혼란을 초래할 수도 있다. 일반적으로 코드 형태의 컬럼이 B케이스가 아닐까 생각된다.

C 케이스의 경우에도, 개인적으로는 CHAR 타입이 좋지 않을까 생각한다. 만약 이 컬럼의 값의 길이가 
자주 변경(10~15자리 사이에서)이 된다면 더더욱 CHAR로 선정함이 더 좋다
하지만 값의 길이가 가변 폭이 크다면 VARCHAR로 선택하는 것이 좋다.

조인시 서로 비교되는 컬럼을 동일 타입으로 유지하는 것 이외에 특별히 "이건 꼭 CHAR로 해야돼" 라고 
생각할 필요는 별로 없어 보인다.
하지만, VARCHAR로 해야 될 것을 CHAR로 적용해서는 무리가 있다.



개인적으로 CHAR VARCHAR를 선정하는 기본적인 절차(상당히 주관적이고 개인적인 판정 절차임)
1. 모든 값이 고정 길이 값인가 ?    -> CHAR
2. 모든 값은 아니어도 대 부분(대략 90% 이상)의 값이 고정 길이이고 자주 변경이 발생하는가 ? -> CHAR
3. 5 바이트 미만의 코드 값인가 ?   -> CHAR
4. 그 이외에는 모두 VARCHAR 로 선정

댓글 없음:

댓글 쓰기