MySQL·phpMyAdmin 한글 깨짐 해결하기

MySQL에 넣은 한글이 ??? 로 바뀌거나 phpMyAdmin과 덤프에서 김민준 처럼 보이나요? 대부분 테이블, 접속(connection), 가져오기 파일의 문자셋이 서로 맞지 않아서 생깁니다. ? 가 아니라 깨진 글자라면 내보낸 파일을 위 상자에서 바로 복구할 수 있습니다.

텍스트와 다음 파일을 지원합니다:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

엑셀 내보내기, 데이터베이스 덤프, 자막, 웹사이트 코드 등.

복구하기

  1. 파일을 끌어다 놓거나 텍스트 붙여넣기
  2. 자동으로 복구
  3. 복사하거나 내려받기
또는 파일을 여기로 끌어다 놓기
  • 업로드 없음. 파일은 브라우저 안에서 복구되며 기기 밖으로 나가지 않습니다.

  • EU 내 서버. Mojibuster는 핀란드(EU)의 서버에서 운영되며 EU 일반 개인정보 보호법(GDPR)이 적용됩니다. GDPR 원문(EUR-Lex, 영어)

MySQL에서 문자셋이 정해지는 세 곳

  • 컬럼·테이블: 데이터를 저장하는 문자셋입니다. 예: utf8mb4, latin1, euckr.
  • 접속: 클라이언트와 서버가 주고받는 문자셋입니다. SET NAMES utf8mb4 나 드라이버 설정으로 정합니다.
  • 파일: 가져오기·내보내기 파일을 읽고 쓰는 인코딩입니다. phpMyAdmin 가져오기 화면의 파일 문자셋 항목에서 고릅니다.

증상 1: 한글이 ???로 저장된다

컬럼이나 접속이 latin1 이면 한글을 담을 수 없어 MySQL이 ? 로 바꿔 저장합니다. 오래된 MySQL 5.x의 기본값이 latin1 이라 예전에 만든 테이블에서 자주 생깁니다. 이렇게 저장된 ? 는 원래 글자 정보가 사라진 것이라 어떤 도구로도 되돌릴 수 없습니다. 설정을 고친 뒤 원본 데이터에서 다시 넣어야 합니다.

증상 2: 김민준 같은 글자가 보인다

애플리케이션이 UTF-8 바이트를 latin1 접속으로 latin1 컬럼에 넣은 경우입니다. 같은 방식으로 읽는 애플리케이션 화면은 멀쩡하지만, 올바르게 접속하는 phpMyAdmin과 내보낸 파일에서는 한글이 깨집니다. 이때는 바이트가 그대로 남아 있어 복구할 수 있습니다.

latin1 컬럼에 들어간 데이터를 phpMyAdmin에서 CSV로 내보낸 경우

깨진 글자

"1","김민준","서울특별시 종로구 세종대로 209","02-1234-5678"

복구 후

"1","김민준","서울특별시 종로구 세종대로 209","02-1234-5678"

문자셋 확인하기

  • SHOW VARIABLES LIKE 'character_set%'; 로 서버와 접속 설정을 봅니다.
  • SHOW CREATE TABLE customers; 로 테이블과 컬럼의 문자셋을 봅니다.
  • SELECT name, HEX(name) FROM customers LIMIT 5; 로 실제 바이트를 봅니다. utf8mb4 컬럼에서 김 은 EAB980 입니다. 3F 는 이미 ? 로 바뀐 글자입니다.

덤프와 내보낸 파일 복구하기

  1. phpMyAdmin에서 SQL이나 CSV로 내보내거나 mysqldump --default-character-set=utf8mb4 를 사용합니다.
  2. 파일을 위 상자에 끌어다 놓습니다. 깨진 부분만 고치고 정상인 한글은 그대로 둡니다.
  3. 무엇이 바뀌었나요? 에서 바뀐 곳을 확인하고 내려받습니다.
  4. utf8mb4 테이블로 가져오면서 파일 문자셋을 utf-8 로 고릅니다.
  5. 실제 테이블을 바꾸기 전에 복사본으로 먼저 시험해 보세요.

처리는 브라우저 안에서만 이루어져 고객 정보가 담긴 덤프도 외부로 나가지 않습니다. 오래된 시스템에서 받은 EUC-KR 덤프라면 EUC-KR을 UTF-8로 변환도 참고하세요.

원인 고치기

  • 새 테이블은 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 로 만듭니다.
  • 애플리케이션 접속도 utf8mb4 로 맞춥니다. PHP PDO라면 DSN에 charset=utf8mb4, JDBC라면 characterEncoding=UTF-8 을 넣습니다.
  • UTF-8 바이트가 latin1 컬럼에 들어 있다면 CONVERT TO 로 바로 바꾸지 마세요. 한 번 더 인코딩되어 더 심하게 깨집니다. 먼저 MODIFY name VARBINARY(255), 다음에 MODIFY name VARCHAR(255) CHARACTER SET utf8mb4 로 바이너리 형을 거쳐 바꾸는 것이 안전합니다.
  • utf8 이 아니라 utf8mb4 를 쓰세요. MySQL의 utf8 은 3바이트까지만 저장해 이모지를 넣으면 오류가 나거나 ? 로 바뀝니다.

자주 묻는 질문

애플리케이션에서는 멀쩡한데 phpMyAdmin에서만 깨지는 이유는?

애플리케이션이 같은 실수를 두 번 하기 때문입니다. UTF-8을 latin1 접속으로 쓰고 같은 방식으로 다시 읽습니다. phpMyAdmin은 올바르게 접속해 실제로 저장된 내용을 보여 줍니다. 이런 현상의 원리는 글자 깨짐이란에서 설명합니다.

이미 ???로 저장된 한글도 복구되나요?

아니요. ? 로 저장될 때 원래 글자 정보가 사라졌습니다. 백업이나 원본 파일에서 다시 가져와야 합니다.

MariaDB도 같나요?

네. MariaDB도 문자셋을 MySQL과 같은 방식으로 다루며 명령도 같습니다.

덤프 파일은 얼마나 커도 되나요?

파일 하나에 100MB까지입니다. 더 큰 데이터베이스는 테이블별로 나눠 내보내세요.

관련 안내