개발 DB에는 데이터가 잘 저장되는데 실 서버 DB에서 데이터가 잘리는 문제가 발생했다.
확인해보니 문자열의 이모지 뒷 내용이 전부 잘린 것으로 확인해서 DDL을 각 DB의 DDL을 비교해봤다.
- (MySQL을 사용하고 있다.)
그런데 개발 서버 DDL과 실서버 DDL이 동일했다. 그런데 왜 데이터가 개발 서버에서만 잘렸지..?
utf8 vs utf8mb4
개발 서버와 실서버의 컬럼은 모두 charset - utf8을 사용하고 있었다.
utf8과 utf8mb4는 어떤 차이가 있을까?
- utf8 - 내부적으로 한 문자당 가변으로 최대 3바이트를 사용한다.
- utf8mb4 - 내부적으로 한 문자당 가변으로 최대 4바이트를 사용한다.
여기서 이모지는 4바이트를 차지한다. 즉 utf8mb4로는 표현할 수 있고, utf8로는 표현할 수 없다.
요즘은 이모지를 많이 사용함에 따라 utf8mb4로 사용하는 것이 일반적이라고 한다.
DDL이 똑같다며!
문제는 DDL이 동일한데 둘다 되거나, 둘다 안되야 맞는거지. 왜 한쪽 서버에서만 잘리냐는 것이다.
찾아보니 MySQL에서는 DB 서버, 테이블, 컬럼, DB 클라이언트 별로 전부 다른 charset을 지정할 수 있다.
아래 SQL을 통해 각 서버의 정확한 설정을 비교해보도록 했다.
mysql> show variables like 'char%';
mysql> show variables like 'collation%';
개발 DB
- character_set_client - utf8mb4
- character_set_connection - utf8mb4
- character_set_database - utf8mb4
- character_set_filesystem - binary
- character_set_results - utf8mb4
- character_set_server - utf8
- character_set_system - utf8
- character_sets_dir - /usr/share/percona-server/charsets/
- collation_connection - utf8mb4_general_ci
- collation_database - utf8mb4_unicode_ci
- collation_server - utf8_general_ci
실 DB
- character_set_client - utf8mb4
- character_set_connection - utf8mb4
- character_set_database - utf8
- character_set_filesystem - binary
- character_set_results - utf8mb4
- character_set_server - utf8
- character_set_system - utf8
- character_sets_dir - /usr/share/percona-server/charsets/
- collation_connection - utf8mb4_general_ci
- collation_database - utf8_general_ci
- collation_server - utf8_general_ci
추가로 각 DB 서버의 테이블의 Collation도 조회했다.
mysql> show table status from schema like '{table}';
개발 DB
- utf8mb4_unicode_ci
실 DB
- utf8_general_ci
결과적으로 총 두가지 속성이 서버 간 다른 것을 확인했다..
- character_set_database
- collation
- Schema
- Table
Collation의 경우 정렬이나 검색 등과 관련된 속성이라서 INSERT 시 데이터가 잘리는 것과는 관계가 없다고 추측했고, 실제로도 속성을 변경해봤지만 INSERT와는 무관했다.
character_set_database를 수정하면서 확인한 결과 해당 부분이 원인임을 알 수 있었다. 즉, 각 DB 서버의 Schema charset이 다른 것이 원인이었으고 아래의 명령어로 변경하여 동일하게 처리를 해주었다.
mysql> ALTER DATABASE {schema} CHARACTER SET = utf8mb4;
# Collation도 같이 수정 (검색 용도)
# mysql> ALTER DATABASE {schema} COLLATE utf8mb4_general_ci;
참고
'Database > SQL' 카테고리의 다른 글
SQL - WHERE 절, ON 절 제대로 이해하기! (0) | 2023.11.21 |
---|---|
DB 인덱스에 대한 오해 (컬럼 1개 vs 2개!) (2) | 2023.09.16 |
MySQL - 락 불필요한 데이터를 잠그는 문제 정리! (+ Index) (0) | 2023.02.17 |
SQL - OneToOne 관계일 때 주의할 점 (+ Unique Key 설정) (0) | 2022.09.08 |
Real MySQL - Replication(복제)란 무엇인가?! (0) | 2022.07.07 |