요약
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
'백엔드' 카테고리의 다른 글
[DB 해킹] MySQL DB 털린 썰 풉니다 (RECOVER_YOUR_DATA) (0) | 2024.12.23 |
---|---|
MySQL 연결 - characterEncoding=utf8mb4 쓰지 마세요! (0) | 2024.12.12 |
[스프링부트] Soft delete 구현 (1) | 2024.12.09 |
[스프링부트] Spring Batch와 적용방법 (3) | 2024.12.09 |
[스프링부트] 복합키 중 자동증가하는값 (ID) 지정 방법: @GeneratedValue.SEQUENCE (1) | 2024.11.07 |