UTF8 VS UTF8MB4
- 영어 등 서구권 언어: 1글자당 1byte
- 한글 등 아시아권 언어: 1글자당 2byte
- UTF-8: 1글자당 1~3byte(가변적)
- utf8mb4: 가변 4byte utf-8 charset
다국어를 지원하기 위해 1~3 가변바이트 charset utf-8이 주로 사용되어왔다. 그러나 emoji 등 새로 개발된 언어는 글자당 4바이트를 차지하므로, 해당 charset으로 설정되어있는 경우 글자가 깨지는 현상이 발생한다. 따라서 mySQL 5.5 이후 버전부터는 utf8mb4 charset을 지원하면서 최대 4바이트까지 문자를 저장할 수 있도록 하고 있다😄
검색이나 로그인 등 다양한 경우에서 대소문자 구분 여부는 중요하다. 예를 들어, 회원가입 시 비밀번호 설정 부분에서는 대/소문자 구분이 필수 조건일 것이다. 반면에, 글자(키워드) 기반 검색창에서는 대/소문자를 구분하지 않고 데이터를 조회하는 편이 더 효율적일 것이다. 따라서 클라이언트가 DB에 연결을 할 때 기본 charset 설정은 매우 중요하다.
기본 charset 설정은 status명령어로 확인하거나, SHOW variables like ~명령어로 확인할 수 있다.
물론 기본 charset 말고도 table단위, column단위로 각각 charset 설정이 가능하다.
그러나 중구난방으로 다 다르게 설정할 경우(utf8-euckr-latin1등등..), mySQL에서 데이터를 넣을 때 오류가 발생해서 겉보기에는 정상적인 글자일수는 있으나, 실제 binary 값은 그렇지 못할 위험이 있다. 이렇게 되면 나중에 애플리케이션 레벨에서 사용자가 원하는 기능대로 제대로 동작하지 않을수도 있으므로('가'를 검색해도 '가'가 나오지 않는..ㅠ) charset을 가능하면 통일시켜주는 것이 좋다~🤸🏻♂️
※ utf8mb4의 등장 이후로, 대부분 이 모드를 사용하고 있으나 간혹 옛날에 생성된 데이터들은 euc-kr로 표기된 데이터들이 아직 존재하기 때문에 꼭 확인해주는 것이 좋다.
문자열을 표기하는 charset 안에는 이 문자열을 어떤 방식으로 정렬할지를 결정하는 collation이 있다.
그 중 utf8(mb4)에서 가장 많이 사용하는 세 방식의 대소문자 구분 여부, 정렬 기준을 비교해보았다.
비교대상: utf8mb4_bin, utf8mb4_general_ci, utf8mb4_unicode_ci
실행환경: macOS Catalina 10.15, MySQL 5.7
대소문자 구분 여부
각각 쿼리에서 collation을 설정한 후, 두 변수의 동일 여부를 비교하였다.
binary의 경우를 제외하고 general, unicode 방식은 대소문자를 같은 글자로 인식하였다.
※ general모드와 unicode 모드에서는 대/소문자를 포함하여 외국어 문자(à, á, â, ä, æ) 모두 같은 'a'로 인식하였다.
정렬 기준 비교
bin모드에서는 binary값(16진수)를 기준으로 정렬하였으나, general과 unicode모드에서는 좀 더 사람이 생각하기에 이상적인(?) 정렬방식으로 정렬되었다. 두 모드에서는 위에서 언급했던 외국어문자를 모두 같은 글자로 인식하기 때문에 같은 레벨로 정렬하는 것이라고 예상된다.
※ utf8_general과 utf8_unicode의 차이는 unicode 방식이 조금 더 넓은 범위의 언어를 지원하여 정렬한다고 한다.
Conclusion
대소문자 구분이 필요한 경우 utf8mb4_bin 방식을,
구분이 필요하지 않은 경우 utf8mb4_unicode_ci 방식을 택하는 것이 이상적으로 보인다.
'MySQL' 카테고리의 다른 글
Character set & Collation (0) | 2021.09.09 |
---|---|
InnoDB flush method (0) | 2021.03.28 |
Year 2038 Problem (0) | 2021.02.26 |
[data type]CHAR형의 pad_char_to_full_length 옵션과 VARCHAR형 비교 (0) | 2021.02.26 |
[InnoDB] Redo Log와 checkpoint age (0) | 2021.02.22 |