한글바이트데이터베이스UTF-8VARCHAR
🗄️한글 바이트 계산이 중요한 이유 — 데이터베이스 설계 완벽 가이드
데이터베이스를 설계할 때 VARCHAR(100)으로 충분하다고 생각했는데 실제로 100자 한글을 저장하려다 오류가 발생한 경험이 있으신가요? 또는 검색 쿼리가 인코딩에 따라 결과가 달라지는 현상을 경험하셨나요? 한글의 바이트 특성을 이해하면 이런 문제를 미리 방지할 수 있습니다.
인코딩별 한글 바이트 수
| 인코딩 | 한글 1글자 | 영문 1글자 | 이모지 | 주요 사용처 |
|---|---|---|---|---|
| UTF-8 | 3바이트 | 1바이트 | 4바이트 | MySQL, PostgreSQL 기본, 웹 표준 |
| UTF-16 | 2바이트 | 2바이트 | 4바이트 | Java, C#, Windows 내부 |
| EUC-KR | 2바이트 | 1바이트 | 미지원 | 레거시 국내 시스템 |
⚠️ MySQL에서 charset=utf8mb4를 사용하면 한글 3바이트 + 이모지 4바이트를 모두 지원합니다. 예전 utf8은 3바이트만 지원하여 이모지 저장 시 오류가 발생합니다.
데이터베이스 VARCHAR 설계 실수
-- 잘못된 설계 (문자 수 vs 바이트 혼동) name VARCHAR(20) -- 20바이트? 20글자? -- MySQL: VARCHAR(n)은 문자 수 기준 (utf8mb4) -- 한글 20글자 = 60바이트지만 VARCHAR(20)으로 저장 가능 ✓ -- Oracle: VARCHAR2(n) 기본은 바이트 기준 -- 한글 20글자 = 60바이트이므로 VARCHAR2(60) 필요 -- 또는 VARCHAR2(20 CHAR) 처럼 CHAR 단위 명시
데이터베이스별 한글 처리 방식
| DB | VARCHAR 기준 | 권장 설정 |
|---|---|---|
| MySQL / MariaDB | 문자 수 | charset=utf8mb4, collation=utf8mb4_unicode_ci |
| PostgreSQL | 문자 수 | encoding=UTF8 (기본값) |
| Oracle | 기본 바이트 수 | NLS_CHARACTERSET=AL32UTF8, CHAR 단위 명시 |
| SQL Server | NVARCHAR는 문자수, VARCHAR는 바이트 | NVARCHAR 사용 권장 |
| SQLite | 문자 수 | UTF-8 기본 지원 |
인덱스 크기 계산
MySQL의 InnoDB 인덱스는 키 최대 길이 767바이트(기본) 또는 3072바이트(innodb_large_prefix 활성화) 제한이 있습니다.
-- utf8mb4 기준 한글 컬럼 인덱스 최대 길이 767 / 4 = 191글자 (기본 설정) 3072 / 4 = 768글자 (large_prefix 활성화) -- 이를 초과하면 아래 오류 발생: -- ERROR 1071: Specified key was too long; max key length is 767 bytes
실무 주의사항
- 이모지를 저장해야 한다면 반드시 utf8mb4 사용 (utf8은 4바이트 문자 미지원)
- 문자열 비교/정렬은 collation 설정에 따라 달라짐 — 한국어는 ci(case-insensitive) 권장
- API에서 받은 한글 문자열을 DB에 저장할 때 연결 charset도 utf8mb4인지 확인
- LIKE '%검색어%' 쿼리는 한글 인덱스를 타지 않으므로 Full-text search 고려
자주 묻는 질문
Python len()으로 한글 길이를 재면 맞나요?
Python3에서 len()은 문자 수를 반환합니다. "안녕"의 len()은 2입니다. 바이트 수가 필요하면 len("안녕".encode('utf-8'))을 사용하면 6이 반환됩니다.
JavaScript에서 한글 문자열 바이트 계산은?
JavaScript의 string.length는 UTF-16 코드 유닛 수입니다. 한글은 1코드 유닛 = 2, 이모지는 2코드 유닛 = 4입니다. UTF-8 바이트가 필요하면 new TextEncoder().encode(str).length를 사용하세요.
기존 utf8 테이블을 utf8mb4로 마이그레이션하려면?
ALTER TABLE 테이블명 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 명령으로 변환 가능합니다. 단, 인덱스 크기 제한에 걸릴 수 있으므로 사전 확인이 필요합니다.
