티스토리 뷰

study/Mysql

한글 깨짐 현상(Mysql)

kwakjun0 2009. 5. 14. 11:26

한동안 IT관련 포스팅이 없는 것 같아서 오래간만에 IT 관련 포스팅을 하나 하려 합니다. 웹 개발을 공부하다보면 항상 많은 분들에게 시련(?)을 안기는 부분중 하나가 바로 웹에서 한글 서비스 인데요. 아무래도 2바이트를 사용하는 한글 코드를 지원하지 않는 환경에서 개발을 하게 되면 이런 상황이 종종 발생하곤 합니다. client-side 언어인 Flex는 독립적으로 작동하게 되면 한글 깨짐이 없다고봐도 무방하지만(Flash Player에서 알아서 처리해주기 때문에) 데이터 통신이 프로젝트에 포함되기 시작하면 상황은 달라집니다. 한글 깨짐 현상이 발생하는 경우는 크게 아래 2가지로 분류 가능합니다.(그 외에 분류도 가능할 수도..)
  • 웹 서버 또는 데이터 베이스 서버가 한글 인코딩을 지원 하지 않는다.
  • 간단하게 사용하는 택스트 에디터에서 사용하는 인코딩이 한글을 지원하지 않는다.
아래부터 Apache 웹 서버, PHP, MySQL의  APM 조합 위주로 설명합니다.
  대부분의 한글 깨짐 현상은 서버 사이드의 문제일 경우가 많습니다. Flex 어플리케이션에서 DB로 부터 데이터를 가지고 오는데 우리가 거쳐야 하는 관문은 우선 직접적으로 웹서버(Apache)를 거쳐 Server-side 언어(PHP)의 통제를 받아 DB서버(MySQL)로 부터 데이터를 가지고 와야 하는데 이 세 관문에서 각각 지원하는 인코딩 설정에 따라서 한글이 깨질수 있습니다. 기본적으로 Apache 웹 서버로 인해 한글이 깨지는 경우가 없습니다. 경우를 아직 경험해 본 적이 없습니다. (httpd.conf 설정파일에 보시면 기본적으로 전세계적을로 쓰이는 모든 언어들이 사용 가능하도록 설정되어 있습니다. AddLanguage 옵션)

httpd.conf 파일의 AddLanguage 옵션


PHP 역시 사용자가 설치 후 따로 default_charset을 정하지 않는 이상 그 값이 'no value'로 설정되어 묻지도 따지지도 않고(으응!? -_-;) 받아들인대로 그 결과값을 출력 합니다. 

PHP core의 문자셋 설정

  서버 사이드에서 가장 많은 문제를 일으키는 놈이 바로 MySQL 입니다. APM 조합으로 처음 웹 개발을 접하시는 분들은 한번씩 경험하는 문제가 바로 이 한글 인코딩 문제이기도 합니다. Apache의 경우 AddLanguage 옵션으로 설정파일에서 여러 언어가 동시에 사용가능하도록 설정해 줄 수 있습니다. PHP는 묻지도 따지지도 않습니다. 문제는 데이터를 직접적으로 다루는 MySQL에서는 Server, DB, Client, Connection 이렇게 기본적으로 4 분야에서 character set을 설정해서 사용하는데 MySQL 5버전을 처음 설치를 하게 되면 latin1으로 설정되어 있습니다. 여기서 바로 문제가 발생합니다. latin1은 latin 알파벳을 지원하기 위한 8비트 코드이기 때문에 한글의 코드 값은 저장할 수 없도록 되 있습니다.

이 죽일놈의 latin1 코드 -_-;

저렇게 설정 되 있는 DB를 가지고 아무리 프로그래밍을 해서 데이터를 넣고 다시 가지고 와봐야 한글은 깨질 수 밖에 없습니다. 넣을때 이미 깨져버린 값을 아무리 불러와도 다시 복구 되지 않는 것이죠. 이런 상황을 해결하기 위해서는 우선적으로 MySQL의 설정파일(my.cnf)을 변경해 줘야 합니다. (아래 내용이 없다면 추가해주세요)
RedHat 계열의 리눅스에서 my.cnf의 위치는 /etc/my.cnf 입니다.(종종 /etc/mysql/my.cnf인 경우도 있습니다.)
[client]
default-character-set=utf8
[mysqld]
character-set-client-handshake=FALSE
init_connect="SET collation_connection = utf8_general_ci"
init_connect="SET NAMES utf8"
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_general_ci

[mysqldump]
default-character-set=utf8
[mysql]
default-character-set=utf8

위에서 문자셋을 utf8로 설정한 이유는 euc-kr로 설정해도 무방하지만 euc-kr을 사용할 경우 지원하지 않는 서비스들이 더러 있고 한국에 있다고 해도 OS에서 euc-kr을 지원하지 않으면 한국사람이 한글을 보지 못하는 경우가 발생합니다. 반면 utf-8코드는 다국어를 지원하는 코드로써 전세계적으로 통용되는 코드이기 때문에 적극 권장되는 코드입니다.(Flex 역시 기본적으로 utf-8 코드를 사용합니다.) 이렇게 설정을 해주게 되면 MySQL의 사용환경이 아래와 같이 변한것을 확인하실 수 있습니다.
 

latin1에서 utf8로 바뀐 모습

아래는 테스트 결과입니다.

한글 입력 테스트

이렇게 MySQL 서버에서도 한글이 지원이 되는데 한글이 여전히 깨지는 경우가 있습니다. 그런 경우는 자신의 텍스트 에디터의 인코딩을 의심해 봐야 합니다. 거의 모든 텍스트 에디터들이 기본으로 ANSI 코드를 지원하는데, 어떤 경우에는 그냥 ANSI 코드로도 별 무리 없이 돌아가는 경우가 있고 한글이 깨지는 경우가 있더라고요. 지금도 여전히 초보이지만 과거에는 이 것 때문에 삽질 많이 했습니다. ㅠ_ㅠ;

대표적인 텍스트 에디터인 에디트 플러스의 저장화면

메모장의 저장화면

  위 두 이미지를 보면 아시겠지만 텍스트 에디터의 기본 저장 옵션은 대부분이 ANSI입니다. 대부분의 텍스트 에디터에서 UTF-8을 지원하므로 인코딩 옵션을 ANSI에서 UTF-8로 변경후 저장하는 습관을 기르는 것이 좋습니다. 이런식으로 서버를 설정해 주게 되면 왠만한 사용자들은 브라우저에서 한글을 볼 수 있습니다. 
  지금 설명드린 방식은 개발자가 MySQL 서버의 관리자 권한을 가지고 있을때의 방법입니다. 만약 DB를 외부에 호스팅을 받고 DB설정이 EUC-KR로 설정되어 있는 경우 PHP에서는 문제가 없을수 있지만 PHP에서 XML형태로 파싱한 데이터를 받은 Flex에서 한글이 깨지는 경우가 있습니다. 이런 경우 PHP로 DB의 내용을 XML 형식으로 파싱할때 변수를 iconv()함수를 통해 인코딩을 변경해서 제공하는 방법이 있습니다.
iconv("입력 문자셋", "출력 문자셋", 문자변수)
ex) $a = iconv("euc-kr", "utf-8", $a); // $a변수의 인코딩을 euc-kr에서 utf-8로 변환
  종종 Flex에서 한글이 깨진다고 하면 System.useCodePage=true 옵션을 추천해 주시는 분들이 많습니다. System.useCodePage는 외부의 텍스트 파일을 해석하는데 있어서 사용하는 코드를 설정하는 속성값입니다. false로 설정되면 기본적으로 unicode를 사용하여 외부 텍스트 파일을 해석하지만(기본값이 false입니다.) true로 설정이 되면 OS나 Flex 어플리케이션이 작동되고 있는 프로그램의 코드를 종속적으로 사용하게 됩니다. 즉 한마디로 Flex 어플리케이션이 Flash player를 통해 어느 플랫폼에서든지 자유롭게 동작할 수 있는 장점을 스스로 제약 하게 되버립니다. Flex Launguage Reference에서도 System.useCodePage=true의 사용을 자제할 것을 권장 하고 있습니다


출처 : 제주소년의 잡다한 이야기들 http://blog.handkstory.net