책을 읽읍시다
아는척 하기 시리즈 - MySQL utf8mb3는 왜 등장했고, 왜 utf8mb4로 바꿔야 하는가 본문
유니코드와 UTF-8에 대한 지식이 없다면 아래 글을 먼저 읽고 오자.
아는척 하기 시리즈 - 유니코드와 UTF-8의 비밀
가끔 개발하다 보면 글자가 깨져서 당황할 때가 있다. 이모지를 썼는데 물음표가 뜬다거나, 아예 처음보는 문자가 나타난다거나 하는 일들 말이다. 사실 이건 대부분 "유니코드(Unicode)"와 UTF-8을
junghwan17.tistory.com
MySQL의 배신? utf8은 왜 진짜 UTF-8이 아닐까
열심히 개발한 서비스, 사용자가 닉네임에 이모지(😂) 하나 넣었을 뿐인데 데이터베이스가 Incorrect string value 오류를 뿜어내며 터져버립니다. 개발자라면 한 번쯤 겪어봤을 이 황당한 상황, 대체 원인이 무엇일까요? 범인은 의외로 가까운 곳에 있습니다. 바로 우리가 철석같이 믿었던 MySQL의 utf8 문자셋입니다.
결론부터 말하겠습니다. MySQL에서 utf8은 우리가 아는 그 표준 UTF-8이 아닙니다. 이 사실을 모른다면, 당신의 데이터는 언제든 깨지거나 유실될 위험에 처해있습니다. 이 글에서는 MySQL이 왜 이런 '반쪽짜리' 문자셋을 만들었고, 우리는 왜 지금 당장 utf8mb4로 갈아타야 하는지 그 역사를 파헤쳐 보겠습니다.
문제의 근원: 3바이트의 덫, utf8mb3
이야기는 2000년대 초반으로 거슬러 올라갑니다. 당시 MySQL은 UTF-8을 지원하기로 결정했지만, 아직 오늘날의 유니코드 표준(RFC 3629)이 확립되기 전이었습니다. 그 시절 개발자들은 "대부분의 문자는 3바이트 안에 다 들어오지 않을까? 4바이트까지 지원하는 건 공간 낭비고 성능에도 좋지 않을 거야"라고 판단했습니다.
이런 시대적 한계 속에서 탄생한 것이 바로 최대 3바이트 문자만 저장할 수 있는 MySQL만의 독자적인 utf8입니다. 훗날 이 '반쪽짜리' 문자셋은 진짜 4바이트 UTF-8과 구분하기 위해 utf8mb3(UTF-8 Most Bytes 3)라는 정식 명칭을 얻게 됩니다.
문제는 여기서 시작됩니다. 우리가 일상적으로 사용하는 이모지(😂, 🐢), 고대 문자, 일부 특수 기호 등은 4바이트를 차지합니다. utf8mb3는 이 문자들을 이해할 수 없는 것입니다.
재앙은 이렇게 찾아온다
utf8mb3를 사용하는 테이블에 4바이트 문자를 저장하려고 하면 어떤 일이 벌어질까요?
- 시나리오: 사용자가 회원가입 시 닉네임에 '개발자🐢'라고 입력합니다.
- DB 상황: user 테이블의 nickname 컬럼이 utf8 (utf8mb3)로 설정되어 있습니다.
- 결과: 데이터베이스는 4바이트 문자인 '🐢'를 처리하지 못하고 Incorrect string value: '\xF0\x9F\x90\xA2' ... 오류를 발생시킵니다.
이것은 단순히 저장이 안 되는 수준의 문제가 아닙니다. 애플리케이션 설정에 따라 오류 없이 데이터가 잘려나가거나(?로 변환), 검색 결과에서 누락되는 등 데이터 정합성에 치명적인 문제를 일으킵니다.
해결사의 등장: 진짜는 utf8mb4다
이러한 혼란을 해결하기 위해 MySQL은 2010년, 마침내 진정한 UTF-8 표준을 지원하는 utf8mb4를 내놓습니다. 이름에서 알 수 있듯, 최대 4바이트까지 문자를 처리할 수 있어 현대 유니코드의 모든 문자를 완벽하게 담아낼 수 있습니다.
utf8mb3와 utf8mb4의 차이는 명확합니다.
구분 | utf8mb3 (가짜 UTF-8) | utf8mb4 (진짜 UTF-8) |
최대 바이트 | 3바이트 | 4바이트 |
문자 지원 | 기본 다국어 평면(BMP)만 지원 | 유니코드 전체(이모지, 특수문자 포함) 지원 ✅ |
호환성 | 1~3바이트 문자는 utf8mb4와 완벽 호환 | 1~3바이트 문자는 utf8mb3와 완벽 호환 |
문제점 | 이모지 등 4바이트 문자 저장 시 오류 또는 데이터 유실 ❌ | 모든 문자를 안정적으로 저장 ✅ |
utf8mb4는 utf8mb3의 모든 기능을 포함하면서 4바이트 문자 처리 능력만 추가된 완벽한 상위 호환 버전입니다. 따라서 utf8mb4를 쓴다고 해서 기존 데이터에 문제가 생기거나 공간 효율이 무조건 떨어지는 것이 아닙니다. 1바이트 문자는 여전히 1바이트로 저장됩니다.
그래서 우리는 무엇을 해야 하는가?
이제 우리가 나아갈 길은 명확합니다. MySQL의 권고 사항 역시 단호합니다. utf8은 앞으로 사라질(deprecated) 유물이니, utf8mb4를 사용하라는 것입니다.
실무적인 조언
- 새로운 프로젝트는 무조건 utf8mb4
- 새로운 데이터베이스나 테이블을 설계할 때는 고민할 필요도 없이 문자셋을 utf8mb4로, 콜레이션(Collation)은 utf8mb4_general_ci 또는 utf8mb4_unicode_ci로 설정해야 합니다. 이것은 이제 선택이 아닌 필수입니다.
- 기존 시스템은 지금 당장 확인하고 마이그레이션을 계획하라
SHOW CREATE TABLE your_table_name;
빠른 시일 내에 utf8mb4로 변경하는 마이그레이션 계획을 세워야 합니다. - 운영 중인 서비스가 있다면, 지금 바로 데이터베이스 문자셋을 확인해보십시오.
결론: 이름에 속지 말자
결론은 간단합니다. MySQL에서 utf8이라는 이름에 속지 마십시오. 그것은 과거의 기술적 한계가 낳은 유물이며, 온전한 데이터를 지키기 위한 우리의 선택은 오직 utf8mb4뿐입니다. 사용자가 어떤 문자를 입력하더라도 데이터가 안전하게 보관될 것이라는 신뢰, 그것이 바로 utf8mb4를 선택해야 하는 이유입니다.
'데이터베이스' 카테고리의 다른 글
아는척 하기 시리즈: 조인 알고리즘의 종류가 왜 이렇게 많이 필요할까? (1) | 2025.06.06 |
---|---|
아는척 하기 시리즈: 유니크 인덱스 (1) | 2025.06.04 |
아는척 하기 시리즈 - InnoDB에서 Primary Key 설계 전략 (4) | 2025.05.17 |
순차 PK vs. UUID: InnoDB 클러스터링 인덱스와 복제 전략 (1) | 2025.05.17 |
데이터베이스에 나오는 CASCADE란 단어는 무슨 뜻일까요? (+ FK와 참조 무결성) (0) | 2025.05.11 |