관리 메뉴

피터의 개발이야기

[RDS] Aurora DB에 이모지 저장하기 본문

Database

[RDS] Aurora DB에 이모지 저장하기

기록하는 백앤드개발자 2022. 7. 7. 05:48
반응형

ㅁ 개요

 ㅇ 시스템 점검 시 SQLException이 발견되었다. 원인은 텍스트 중에 포함되어 있던 이모지를 디비에 Insert할 때에 Incorrect string value 에러가 발생하였고, 이를 조치하는 과정을 정리하였다.

 

 

ㅁ 에러 확인

uncategorized SQLException; SQL state [HY000]; error code [1366]; (conn=322423) Incorrect string value: '\xF0\x9F\x8E\x81\xEB\xA8...' for column 'FORMATTEDSTRING' at row 1; nested exception is java.sql.SQLException: (conn=322423) Incorrect string value: '\xF0\x9F\x8E\x81\xEB\xA8...' for column 'FORMATTEDSTRING' at row 1

 ㅇ 등록하는 데이터에 "🎁" 작은 선물이 담겨져 있었다. 이모지는 UTF-8로 인코딩 시 글자가 4 bytes까지 커지게 된다. 이럴 경우 Mysql / MariaDB / AuroraDB-Mysql에서만 문제가 된다. Mysql은 최대 3 bytes까지만 지원하도록 설계가 되었기 때문이다.  참조 페이지

 

1) 다국어를 처리할 수 있는 UTF-8 이라는 저장방식이 있음. 원래 설계는 가변4바이트임.
2) 전세계 모든 언어문자를 다 카운트 해봤는데 3 바이트가 안됨.
3) MYSQL/MariaDB 에서는 공간절약+속도향상 을 위해서 utf8 을 가변3바이트로 설계함.
4) Emoji 같은 새로나온 문자가 UTF-8의 남은 영역을 사용하려함 (4바이트 영역).
5) MYSQL/MariaDB 에서 가변4바이트 자료형인 utf8mb4 를 추가함.  (2010년 3월에).

 

 

 

ㅁ 테스트 환경 세팅 및 테스트

 ㅇ 회사의 개발 환경은 AWS이기 때문에  AuroraDB 환경설정을 바꾸는 작업은 쉽지 않다.

 ㅇ 테스트의 용이성을 위해 시스템 환경설정을 쉽게 바꿀 수 있는 로컬 환경을 구성하였다.

 ㅇ Docker를 이용해 쉽게 Mysql 환경을 구축하였다. 예전 글

 ㅇAuroraDB-Mysql과 최대한 동일한 환경을 구축하기 위해 Mysql:5.7 도커이미지를 사용하여 구성하였다.

 

 

 ㅇ 동일한 에러가 뜨는지 확인하기 위해 기존 utf8 charset을 사용하는 TEST1 테이블을 만들었다.

 

 ㅇ Incorrect string value 에러가 동일하게 발생하였다.

 

 ㅇ 이번엔 utf8mb4 charset으로 TEST2를 생성하였다.

 

 

 ㅇ 정상적으로 데이터가 들어가는 것을 확인하였다.

 

 

ㅁ Docker Mysql 설정

 ㅇ Mysql의 시스템의 character set은 이미 utf8mb4로 세팅이 되어 있어서 따로 수정할 사항은 없어보였다.

 ㅇ Table의 charset을 변경하여 insert 테스트를 해 보았다.

 

ㅁ RDS 수정작업

alter table TEST1 convert to character set utf8mb4;

 ㅇ TEST1 테이블의 character set을 utf8mb4로 변경하였다.

 ㅇ 기존 insert 에러가 발생했던 insert문을 재시도하여 성공하여 입력된 데이터를 확인할 수 있었다.

 ㅇ 결론적으로 테이블의character set이 utf8이어서 문제가 발생한 것이었다.

 

 

ㅁ Redis의 이모지 영향도 파악

 ㅇ 시스템 안정성을 위해 Redis에 이모지가 등록될 때에 영향도도 조사해 보았다.

 ㅇ Redis에는 Binary의 형태로 들어가고 있었다.

 ㅇ Binary는 0과 1, 두 숫자로만 이루어진 메모리형태를 의미하며, 텍스트가 아닌 이진으로 인코딩된 형태이기 때문에 인코딩에 상관없이 모든 데이터를 수용할 수 있다.

 ㅇ 그래서 이모지형태의 데이터의 입력에는 문제가 없었다.

 

 

ㅁ 함께 보면 좋은 사이트

https://www.letmecompile.com/mysql-utf8-utf8mb4-migration/

 

MySQL utf8에서 utf8mb4로 마이그레이션 하기

Emoji같은 글자들은 utf8 인코딩 되는경우 글자당 최대 4bytes까지 필요하다. 하지만 기존 MySQL의 utf8 필드의 경우 글자당 최대 3bytes 까지만 지원하는 한계점이 있었다. 때문에 MySql database에서 utf8mb4

www.letmecompile.com

https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html

 

MySQL :: MySQL 8.0 Reference Manual :: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)

10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding) The utf8mb3 character set has these characteristics: Supports BMP characters only (no support for supplementary characters) Requires a maximum of three bytes per multibyte character. Applica

dev.mysql.com

 ㅇ https://blog.lael.be/post/917

 

[MySQL/MariaDB] utf8mb4 언어셋 소개 및 표현범위.

기술이 매우 빠르게 발전한다. 배워도 배워도 계속 배워야 한다.   최근에 라엘이가 앞으로 100년동안은 나타나지 않을 것이라고 예상했던, 4 Byte UTF-8 문자열을 보고 여러 깨닳은 바가 있었고

blog.lael.be

 ㅇ https://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%EB%84%88%EB%A6%AC

 

바이너리 - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org

반응형
Comments