백엔드

MySQL 한글 (인코딩) 에러 났을 때 해결방법

KyuminKim 2024. 12. 9. 16:34

요약

1. /etc/my.cnf 파일 수정

2. mysql 접속 후 DB Character Set 수정

3. mysql 접속 후 Table column의 collation 수정

4. DB 접속 시 인코딩 지정


배경

스프링부트를 이용해 백엔드 서버를 제작했고, 

MySQL DB 서버를 제작했다.

 

이때, API request body에 한글이 들어가면

백엔드 서버에 이런 Incorrect String Value 에러가 뜬다 !!

 

개발환경

  • DB 서버 -  mysql server 버전 5.7.44
  • OS - Linux CentOS

에러 원인

mysql 인코딩 문제때문에 한글을 인식하지 못해 발생한 문제이다!


해결 과정

1. /etc/my.cnf 파일 수정

 

파일을 write할 수 있도록 권한을 상승시키자

sudo chmod 666 /etc/my.cnf

 

그 후 파일 맨 아래에 아래 코드를 붙여넣자

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

 

최종 /etc/my.cnf 파일은 다음과 같다.

# /etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
bind-address = 0.0.0.0

character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

 

상승시켰던 파일의 권한을 다시 원래대로 바꾸자!

(이 작업을 하지 않으면 mysql: [Warning] World-writable config file '/etc/my.cnf' is ignored.  에러가 발생할 수 있다)

sudo chmod 644 /etc/my.cnf

sudo chown root:root /etc/my.cnf

sudo systemctl restart mysqld

 

 

2. mysql 접속 후 DB Character Set 수정

 

1번만으로는 되지 않아, 직접 mysql에 접속해 설정했다.

(이미 생성된 DB의 설정을 바꿔야 해서 적용이 안 된 것으로 추정)

 

mysql 접속

mysql -u root -p
# 비밀번호 입력

 

character set 설정

ALTER DATABASE (db이름) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

 

 

3. mysql 접속 후 Table column의 collation 수정

 

여전히 안된다! 

그렇다면 DB Table에서 일일이 설정해주면 된다.

 

mysql 접속

mysql -u root -p
# 비밀번호 입력

 

변경할 DB 명시

use (db이름)

 

DB Table 조회

SHOW FULL COLUMNS FROM (table명);
+-----------------+---------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+
| Field           | Type          | Collation         | Null | Key | Default | Extra          | Privileges                      | Comment |
+-----------------+---------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+
| id              | bigint(20)    | NULL              | NO   | PRI | NULL    | auto_increment | select,insert,update,references |         |
| name            | varchar(255)  | latin1_swedish_ci | YES  |     | NULL    |                | select,insert,update,references |         |

(생략)
+-----------------+---------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+

 

name 필드의 collation이 latin1_swedish_ci로 되어있다!

이것을 (인코딩은) utf8mb4로, (collation은) utf8mb4_general_ci 로 바꿔주자 

ALTER TABLE (table명)
MODIFY name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

 

 

4. DB 접속 시 인코딩 지정

 

백엔드 서버에서 접속하는 DB의 url을 수정하자

useUnicode=true&characterEncoding=utf8mb4을 덧붙여 아래와 같이 설정한다

# application.yml

spring:
  datasource:
    url: jdbc:mysql://{db연결주소}:3306/{db명}?useUnicode=true&character_set_server=utf8mb4

 

 

이렇게 해주면

드디어 !!!

한글 인코딩 에러가 나지 않는다 !!!


여담

위 과정을 통해 해결할 수 있었다.

 

해결하는 과정에서 알게된 용어를 정리해보자

 

 

utf8mb4는 뭘까?

인코딩 방식 중 하나로,

 

utf8과 달리 이모지 문자를 허용하는 것이 가장 큰 특징이다

 

utf8 - (한글자 표현) 3바이트 사용

utf8mb4 - (한글자 표현) 4바이트 사용

 

이모지는 4바이트이기 때문에, utf8로는 사용할 수 없다고 한다 

 

참고로 mysql 기본 charset은 latin1로,

이것은 한글을 지원하지 않기 때문에 명시적으로 바꿔줘야 함을 잊지 말자!

 

공식문서에 따르면 mysql 버전 8.0부터 utf8을 지원한다고 한다!

 

 

collation은 뭘까?

latin1_swedish_ci 였던 collation을 utf8mb4_general_ci 로 변경했다.

 

이때

collation은 Database에서 문자열의 정렬 기준을 말한다고 한다

 

문자열을 비교, 정렬하기 위해 정의한 규칙으로

각 character set마다 default collation이 존재한다고 한다.

(latin1의 경우 latin1_swedish_ci)

 

 

다음 작업시에는 MySQL 인코딩도 신경써야겠다!


참고

- collation https://dev.mysql.com/doc/refman/8.4/en/charset-mysql.html

- MySQL 8.0 release https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-1.html