[TIL] mysql 이모티콘 저장 실패

반응형

1. 문제

erorr가 올라오는 slack 채널에 이모티콘 🤪 저장이 실패했다는 에러가 종종.. 올라오고 있었습니다.

'아니? 현대의 데이터베이스에 이모티콘이 저장이 안될 수 가 있나..?' 라는 생각과 함께 해당 오류가 발생하고 있는 table의 character set을 확인하기위해 다음과 같은 명령어를 입력해보았습니다.

SHOW FULL COLUMNS FROM mytable;

그 결과 현재 서비스에서 실 사용중인 table의 character set이 utf8로 설정된 것을 확인할 수 있었습니다.

아.. utf8mb4가 아니라 utf8로 설정이 되어 있었구나.. 그랬구나?

2. 원인

원인은 utf8mb4로 설정되어 있어야 할 character set이 utf8로 설정되어 있었기 때문입니다.

그럼 utf8과 utf8mb4의 차이점은 뭔데?..

이를 이해하기 위해서는 먼저 '유니코드(Unicode)'와 'UTF-8'에 대해 이해할 필요가 있습니다.

2-1) 유니코드(Unicode)

유니코드란 전 세계의 언어를 코드와 1:1로 매핑시켜놓은 '코드표' 입니다.

유니코드 탄생 이전에는 표준이 존재하지 않았기에 많은 혼란이 있었고 다음과 같은 문제점이 있었습니다.

예를 들어 A라는 업체가 자신들 만의 표준을 만들어 '가'는 0001로 '나'는 0010로 '다'는 0100로 표현하기로 합니다.

이때 B라는 업체는 자신들 만의 표준을 만들어 '가'는 0100로 '나'는 0010로 '다'는 0001로 표현하기로 합니다.

위와 같은 상황에서 컴퓨터는 어떠한 표준을 따라서 화면에 언어를 보여줘야할지 판단을 할 수 가 없게 된 것입니다.

이로인해 어릴 때에는 가끔씩 특정 홈페이지에 들어가보면 글자가 깨져서 정상적으로 출력되지 않았던 역사가.. 있었습니다.

헷갈려! 전 세계의 언어를 하나의 표준으로 통일하자! 😡

해서 나온게 유니코드이며 유니코드의 사전적 설명은 다음과 같습니다.

유니코드(Unicode)는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이며, 이를 이용해 각 나라의 언어를 컴퓨터 상에서 일관된 방식으로 다룰 수 있게 되었습니다.

2-2) UTF-8

utf-8은 유니코드의 코드를 어떻게 컴퓨에 저장해야 하는가?에 대한 변환 방식을 의미합니다.

이를 인코딩(encoding)이라고 하는데, utf-8은 풀어서 쓰면 유니코드 변환 형식(Unicode Transformation Format)이므로 당연한 이야기 입니다.

예를 들어 유니코드로 '가'는 0001로 '나'는 0010으로 정의했다고 가정해보겠습니다.

이제 컴퓨터는 해당 유니코드 값을 어떻게 저장할지를 정해야 합니다.

'가나'를 저장할 경우 컴퓨터는 글자당 1byte를 할당해 2byte(00000001 00000010)로 저장할 수도 있고 글자당 2byte를 할당해 4byte(00000000 00000001 00000000 00000010)로 저장할 수 도 있습니다.

이처럼 유니코드 값을 어떻게 컴퓨터에 저장할 것인가?에 대한 표준 변환방식이 utf-8이며, utf-8은 가변 인코딩 방식을 채택해 유니코드 값을 저장하기로 정의했습니다.

이때 가변인코딩이란 글자마다 byte의 길이를 다르게 저장한다는 의미로 예를 들어 'a'는 1byte로 '가'는 3byte로 변환해 저장하는 방식입니다.

2-3) utf8 vs utf8mb4

자 이제 다시 본론으로 돌아가 mysql의 utf8과 utf8mb4의 차이점에 대해 알아보겠습니다.

우리는 이제 utf8이 유니코드 값을 가변으로 저장하는 인코딩 방식임을 알고 있습니다.

utf8 방식이 처음 나왔을때 mysql도 utf8 방식을 지원하기위한 시스템을 설계 했는데,

당시 "전세계의 모든 언어가 21bit (3byte)에 저장되는군? 3byte 가변 자료형으로 설계하면 효율적이겠군" 이라는 판단하에 mysql의 utf8은 3byte 가변 자료형으로 설계되버렸습니다.

그 결과, 최근에 나온 4byte 문자열(이모티콘 과 같은것들..)이 mysql의 utf8 지료형에 저장 될 경우 값이 손실되는 현상이 발생해 에러가 발생하게 된 것입니다.

이후 위와 같은 문제를 해결하기위해 4byte 문자열도 저장할 수 있는 자료형을 mysql 에서 내놓았는데 이것이 바로 'utf8mb4' chartset 입니다. 😓

즉 mysql에서 utf8mb4는 가변 4byte 텍스트 자료형, utf8은 가변 3byte 텍스트 자료형을 의미합니다.

3. 해결

dba님에게.. 해당 table의 text charset을 utf8mb4로 변경해달라고 요청드리면 됩니다.

charset을 변경하면 반드시 그에 맞는 collation도 변경하도록 요청드려야 하며,

상용 환경 테이블의 경우 해당 작업시 table lock이 걸리게 되므로 이를 고려해 작업을 요청드리면 되겠습니다.

또한 신규로 생성하는 테이블의 경우에는 utf8mb4로 텍스트 자료형을 선택하는 것이 좋을 것 같습니다.


반응형

댓글

Designed by JB FACTORY