2025년 10월 21일

문자 집합의 발전 과정과 MySQL utf8mb3 vs utf8mb4 차이

사전 지식 정리

  • 문자 집합(character set): 컴퓨터가 이해할 수 있는 문자들의 집합
  • 문자 인코딩(character encoding): 문자 집합에 속한 문자를 컴퓨터가 이해하는 0과 1로 이루어진 문자 코드로 변환하는 과정
  • 문자 디코딩(character decoding): 반대로 0과 1로 표현된 문자를 사람이 이해하는 문자로 변환하는 과정
 

아스키(ASCII, American Standard Code for Information Interchange)

  • 초창기 컴퓨터에서 사용하던 문자 집합 중 하나
  • 영어의 알파벳과 아라비아 숫자, 일부 특수 문자를 포함
  • 하나의 아스키 문자를 표현하기 위해서는 8비트(1바이트)를 사용
  • 8비트 중 1비트는 패리티 비트(parity bit). 실질적으로 문자 표현을 위해 사용되는 비트는 7비트
  • 7비트로 표현할 수 있는 정보의 가짓수는 2^7개이므로 총 128개의 문자를 표현 가능
 
notion image
 

EUC-KR

  • 한글을 표기할 수 없는 아스키 코드의 한계를 극복하기 위해 등장한 한글 인코딩 방식 중 하나
  • EUC-KR은 KS X 1001, KS X 1003이라는 문자 집합 기반의 인코딩 방식으로, 아스키 문자를 표현할 때는 1바이트, 하나의 한글 글자를 표현할 때는 2바이트 크기의 코드를 부여
  • 2바이트(16비트)는 네 자리 16진수로 표현할 수 있으므로 EUC-KR로 인코딩된 한글 글자 하나는 네 자리 16진수로 표현 가능
  • 예를 들어, '가'의 경우 0xb0a1로 인코딩 됨.
  • EUC-KR 인코딩 방식을 사용하면 총 2,350개 정도의 한글 단어를 표현 가능
  • 하지만 여전히 모든 한글 조합을 표현하지는 못했음. ('쀓', '똠'과 같은 문자는 EUC-KR로 표현 불가능)
 
notion image
 

유니코드(unicode)

  • 유니코드는 한글을 포함해 EUC-KR에 비해 훨씬 많은 언어, 특수문자, 화살표, 이모티콘까지 코드로 표현할 수 있는 통일된 문자 집합
  • 유니코드는 대부분의 언어를 지원하기 때문에 국가별로 다른 문자 집합과 인코딩 방식을 준비할 필요가 없음.
  • 그 덕분에 유니코드는 현대 가장 많이 사용되는 표준 문자 집합으로 자리 잡음.
  • 유니코드 문자 집합 상에서 '가'라는 글자에 부여된 값은 0xAC00 (코드 포인트로 표현하면 U+AC00)
 
notion image
 
  • ⭐️⭐️⭐️ 아스키 코드나 EUC-KR은 글자에 부여된 값을 그대로 인코딩 값으로 삼았지만, 유니코드는 조금 다름.
  • 글자에 부여된 값 자체를 인코딩된 값으로 삼지 않고, 이 값을 다양한 방법으로 인코딩 함.
  • 이러한 인코딩 방법에는 대표적으로 UTF-8, UTF-16, UTF-32 등이 존재
  • 요컨대, 유니코드가 문자의 집합이라면 UTF-8, UTF-16, UTF-32는 유니코드 문자에 부여된 값을 인코딩하는 방식을 의미
 
notion image
 
  • UTF-8, UTF-16, UTF-32는 가변 길이 인코딩 방식
  • 예를 들어, 아래와 같이 '한'이라는 같은 문자에 대해서도 다른 인코딩 결과가 도출되는 모습을 확인할 수 있음.
    • utf-8 한: ed959c utf-16 한: fffe5cd5 utf-32 한: fffe00005cd50000
       

UTF-8

  • UTF-8은 유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나
  • 8-bit 단위로 문자를 인코딩한다는 의미 (즉, 1바이트 = 8비트 단위로 유니코드 코드 포인트를 쪼개서 저장)
  • 대부분의 웹사이트의 경우 UTF-8을 사용
  • UTF-8은 문자 하나를 표현하기 위해 적게는 1바이트에서 많게는 4바이트를 사용
    • 1바이트 (U+0000 ~ U+007F): ASCII 코드 전체
    • 2바이트 (U+0080 ~ U+07FF): 일부문자 (제어문자, 라틴어, 음성기호, 조정문자, 결합문자, 그리스어, 아랍어 등등..)
    • 3바이트 (U+0800 ~ U+FFFF): 대부분의 문자들. 한국어, 중국어, 일본어는 여기에 포함.
    • 4바이트 (U+10000 ~ U+10FFFF): BMP에 속하지 않는 문자 전부 (이모지, 확장 한자, 고대 문자, 일부 특수 기호 등)
  • UTF-8는 1바이트부터 4바이트까지 문자를 나타내기 위해 사용되는 비트 패턴이 다름.
  • 1바이트만 사용되는 문자는 첫 비트에 0을 두고, 나머지 7비트로 문자를 표현 (ASCII의 인코딩 체계와 동일)
  • 문자를 표현하는데 2바이트 이상 사용되는 경우, 아래 표 처럼 첫번째 바이트에 총 몇바이트를 사용하는지 알리는 비트를 먼저 넣음. (2바이트는 110, 3바이트는 1110, 4바이트는 11110)
  • 그리고 이후 바이트는 10으로 시작
 
notion image
 
  • 이런 패턴을 사용함으로써 첫 바이트 시작 패턴이 문자의 시작임을 명확히 나타내고, 이후 10으로 시작하는 연속 바이트는 문자의 나머지 부분임을 명시 가능
  • 즉, 임의의 바이트 시퀀스에서 명확하게 문자의 경계를 나타낼 수 있게 됨.
  • 이를 통해 데이터 손상, 전송 오류 상황에서도 명확히 문자의 시작과 끝을 식별 가능
 
notion image
 
  • 예를 들어, '곰' 이라는 글자를 UTF-8 인코딩 하면 다음과 같이 인코딩된다.
    • 첫번째 바이트: 맨 앞에 1110을 두고, 상위 4비트를 가져온다. -> 11101010
    • 두번째 바이트: 맨 앞에 10을 두고, 이어지는 6비트를 가져온다. -> 10110011
    • 세번째 바이트: 맨 앞에 10을 두고, 나머지 6비트를 가져온다. -> 10110000
  • 따라서 '곰' 이라는 글자는 111010101011001110110000 로 인코딩된다.
더 자세한 인코딩 과정이 궁금하다면 후디님의 블로그 글을 참고하기!
 

MySQL utf8mb3 vs utf8mb4

  • MySQL에서 utf8mb3utf8mb4는 유니코드 문자를 저장하는 방식을 의미하지만, 지원하는 문자 범위가 다름.
 

1️⃣ utf8mb3

  • 이전 MySQL 버전에서 사용된 "3바이트 유니코드" 인코딩
  • BMP(Basic Multillingual Plane) 영역의 문자만 저장 가능 (즉, U+0000~U+FFFF 범위)
  • 한글, 대부분의 일반 문자, 숫자, 특수 문자는 저장 가능
  • 이모지, 일부 중국, 일본 확장 문자 등은 저장 불가
 

2️⃣ utf8mb4

  • MySQL 5.5 이후 권장되는 "4바이트 유니코드" 인코딩
  • 모든 유니코드 문자 저장 가능 -> BMP 외 문자, 이모지, 다양한 특수 기호 포함
  • MySQL에서 사실상 현대 표준 문자셋
 

왜 MySQL은 utf8mb4를 초창기에 지원하지 않았나?

  • MySQL 초창기에는 UTF-8 전체 범위(4바이트까지) 지원이 필요 없다고 판단
  • 당시 대부분의 사용자는 이모지, 확장 문자 등은 거의 사용하지 않았음
  • 그래서 UTF-8의 3바이트만 지원하도록 설계 -> utf8mb3
    • mb3에서 3은 maximum 3 bytes per character 의미
  • 또한, 당시 서버 자원이 제한적이었기 때문에 3바이트로 제한해서 사용했음. (4바이트까지 지원하면 인덱스, 테이블 크기, 메모리 사용량 증가)
  • 이후 4바이트 유니코드 수요가 증가하면서 utf8mb4가 등장
 

참고 자료

  • '이것이 취업을 위한 컴퓨터 과학이다' 책 p51~p57