해당 내용은 인프런 Real MySQL 시즌1 - PART 1 강의를 참고하여 작성한 것입니다.
공통점
- 문자열 저장용 컬럼
- 최대 저장 가능 문자 길이 명시
- 바이트 수 X → CHAR(10)이면 문자 종류 관계없이 10글자
차이점
- 값의 실제 크기에 관계없이 고정된 공간 할당 여부
- 최대 저장 길이 : CHAR(255) vs VARCHAR(16383) → (65535바이트)
- 저장된 값의 길이 관리 여부 (VARCHAR와 가변 길이 문자셋 사용하는 CHAR는 저장된 값 길이 관리)
- 0~255 bytes → length-bytes : 1
- 256~65535 bytes → legnth-bytes : 2
저장 방식
Latin1
CHAR(10)
4바이트를 넣으면 6바이트를 공백으로 관리한다.
VARCHAR(10)
4바이트를 넣으면 길이 저장용 1바이트 & 문자 데이터 4바이트로 관리한다.
UTF8MB4
CHAR(10)
예약하는 공간 크기가 달라진다.(가변길이 문자 셋인 경우, 길이 저장용 바이트를 사용한다.)
10 한 O O 글 O O 공백 공백 공백 공백
위와 같이 한글 2글자의 경우, 바이트 수 기준으로 공백 4개를 둔다. (O의 경우 연속된 바이트다)
12 한 O O 글 O O 연 O O 습 O O
4글자의 경우, CHAR(10) 컬럼에는 12 바이트를 사용하고, 미리 예약하는 빈 공백 공간이 없다.
즉, VARCHAR과 유사한 방식으로 동작한다.
VARCHAR(10)
문자당 바이트 수가 달라도 문자 셋 관계없이, 꼭 필요한 만큼만 공간 사용
→ Latin1과 유사
CHAR 타입의 공간 낭비 가능성
- 일반적으로 알고 있는 CHAR vs VARCHAR
- 고정된 길이의 값 저장은 CHAR 타입, 그 외의 경우 VARCHAR 타입
- 하지만? 고정된 길이라고 한다 해도, VARCHAR의 경우 매번 1바이트만 더 사용하기 때문에 그렇게 큰 문제가 되지는 않을 것이다.
- CHAR 대신 VARCHAR을 사용한다면?
- 어떤 경우에는 CHAR 타입의 공간 낭비가 심하다.
- 저장되는 문자열의 최소 최대 길이 가변 폭이 큰 경우(ex. 1~ 100)
- 그렇지 않은 경우도 있다.
- 저장되는 문자열의 최소 최대 길이 가변 폭이 작은 경우(ex. 90~100)
- 저장되는 값의 길이 변동이 크지 않다면 낭비는 크지 않다.
- 어떤 경우에는 CHAR 타입의 공간 낭비가 심하다.
컬럼 값의 길이 변경 시 작동 방법
CHAR
이미 공간을 확보해 두었기 때문에 값이 변경되어도 할당된 공간에 값만 변경시키면 된다.
VARCHAR
바이트 수가 변경되기 때문에 해당하는 공간을 재할당 할 필요가 생긴다.
VARCHAR(10)에 4글자를 넣어둔 경우를 생각해 보자.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D |
O | O | O | O | 4 | A | B | C | D | O | O | O | O | O |
인덱스 4가 길이, 5~8이 값을 저장하기 위해 쓰였고, 나머지 인덱스는 다른 필드의 값을 저장한다.
이때 만약 VARCHAR(10) 필드의 값을 ABCD → ABCDE로 변경한다면?
인덱스 D까지의 공간을 모두 delete marking 한 뒤 새롭게 빈 공간에 레코드를 저장한다.
문자열 타입 선정
위의 값 길이 변경 시 작동 방법을 보면 느낌이 왔을 것이다.
- VARCHAR 보다 CHAR이 좋은 경우
- 값의 가변 길이 범위 폭이 좁고
- 자주 변경되는 경우(특히 인덱스 된 컬럼인 경우)
- VARCHAR 사용 시
- 데이터 페이지 내부의 조각화 현상 가능성 증가
- CHAR 타입보다 공간 효율 떨어짐
- 내부적으로 빈번한 Page Reorganize 작업 필요
'DB > MySQL' 카테고리의 다른 글
[MySQL] DETERMINISTIC vs NOT DETEMINISTIC (0) | 2025.10.11 |
---|---|
[MySQL] VARCHAR vs TEXT (0) | 2025.10.11 |
[MySQL] Spatial Query Index 최적화(공간 쿼리 최적화) (1) | 2025.08.31 |
[MySQL] DATE 자료형 정리 (3) | 2024.11.20 |
[MySQL] 날짜, 시간 표기 방식 DATE_FORMAT() (1) | 2024.11.19 |