MySQL character 설정

고개님이 테드폴허브에서 캐릭터셋 처리에 대해 문의해 오셨고 다음과 같은 내용을 보내오셨습니다. 

제가 테스트를 해보니, 좀 더 확인해봐야겠지만....
jdbc connection string 에 characterEncoding 을 지정하지 않은경우, 서버의 character_set_server 값을 가져와 session의 character_set_client, character_set_connection, character_set_results 를 서버의  character_set_server 값으로 맞춰주게 됩니다.

이때, 억지로 set names를 하게되면, 위의 3개의 변수들은 set names 의해 변경된 값이 되어버리는데요 이때 문제가 발생합니다. 

현재 문제가 되는 경우는 "데이터가 euckr 이고, 서버의 character_set_server가 euckr 로 설정되어 있고. Tadpole의 JDBC connection string에서 characterEncoding 을 지정하지 않으면서 set names utf8 이 실행되는 경우입니다.

A) 서버의 character_set_server 변수를 가져와, 통신하는 character set과 character_set_client, character_set_connection, character_set_results 의 값을 euckr 로 내부적인 세팅을 거칩니다.
B) 여기서 set names utf8을 하게 되면 (information_schema의 database character set=utf8), character_set_client, character_set_connection, character_set_results 이 utf8 로 변경되지만, 여전히 통신하는 character set 은 euckr 이 됩니다.

그렇다면, 다음과 같은 에러가 발생합니다.
        Illegal mix of collations (euckr_korean_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

   -- 내부(IMPLICIT)적인 데이터는 euckr_korean_ci 이지만, set names 에 의해 강제로 변환(COERCIBLE)한 utf8_general_ci 과는 연산을 할 수 없다. 
   -- 통신은 euckr 로 하지만, 데이터를 주고 받는형태는 utf8이기 때문입니다. 

   이문제를 피해가기 위해서는 set names 와 jdbc connection 옵션의 character set은 같은 값을 가져야 정확한값을 도출할 수 있습니다. (jdbc connection string을 지정하지 않은 경우 character_set_server 의 값이 적용됨)


아래의 조건하에서 TEST가 필요해 보입니다.
 * JDBC connection string 에서 characterEncoding=utf8 로 넣어주시고, set names 구문을 날리지 않고 비교작업을 진행해주세요. (통신 character set만 utf8이라고 알려주고, mysqld에게 모든 변환을 맡기는 방법)

하여서... 

테드폴허브 에서 MySQL Character 설정은 다음과 같습니다.

데이터베이스 목록을 사용자가 처음 접속하면 

  • show variables like 'character_set_database'  의 실행 결과를
  • set names '%s' 으로 실행합니다.

또한 위의 과정은 사용자가 에디터를 오픈할때, 에디터에서 스키마를 변경할때 위의 과정으로 set name를 해주게됩니다. 

여기에서는 MySQL 데이터베이스에 모두 같은 character schema 라면 문제가 되지 않습니다. 
문제는 schema마다 다른 character이거나 혹은 테이블, 특정 컬럼이 다른 character일때 문제가 됩니다. 

utf8문자가 깨지는 것을 확인했습니다. 


테스트 환경

  • MySQL 5.7.22
  • JDBC Driver MySQL Connector Java mysql-connector-java-5.1.46

현재 환경 (set name을 해 주었을 경우, connect 문자열에 characterEncoding=utf8 이 설정되지 않음)

  • 이미 입력된 데이터의 한글이 깨져 보이지 않지만, 데이터 입력시(insert, update) 한글이 깨짐. 

set name을 해주지 않았을 경우.  (connect 문자열에 characterEncoding=utf8 이 설정 함)

  • 이미 입력된 데이터의 한글이 깨져 보이지 않고, 데이터 입력시(insert, update) 한글이 정상으로 보이고, 깨지지 않는 것을 확인. 

set name을 해주지 않았을 경우.  (connect 문자열에 characterEncoding=utf8 이 설정하지 않음)

  • 이미 입력된 데이터의 한글이 깨져 보이지 않지만, 데이터 입력시(insert, update) 한글이 깨짐. 

(작성 중....)

앞으로 다음과 같은 방법으로 개선하는 것이 좋겠습니다. 

  • MySQL연결 문자열에 characterEncoding=utf8 를 기본으로 붙여 준다.
  • 임으로 set name을 해주지 않는다.
    • 다만, 사용자가 임으로 옵션을 주었을 경우 해준다.

<span id="pageNum"/>