[MySQL - Character set & Collation]

Character Set이란,
캐릭터 셋을 명시적으로 설정하지 않으면 MySQL 5.7 이하는  latin1, MySQL 8은 utf8mb4 가 된다. 
현재 character set 확인은 다음과 같이 mysql 클라이언트로 연결한 후에 status 명령어로 알수 있다.
문자의 집합으로 즉, 텍스트 데이터에 대한 저장공간의 크기를 지정하기 위함이다.
대표적으로는 utf8, euckr 그리고 utf8mb4가 있다.

 

 
Collation이란, 
정렬방식으로 저장된 텍스트 데이터를 정렬할 경우 어떻게 비교하여 정렬할 것인가에 대해 지정하기 위함이다.
"ORDER BY 'text' ASC"에 대해 데이터로 a, b, A, B가 있을 경우 어떤 방식으로 비교하여 정렬을 할 것인가를 지정하는 것이다.
주로 많이 사용되는 collation은 utf8_bin(or utf8mb4), utf8_general_ci(or utf8mb4_general_ci) 그리고 utf8_unicode_ci(or utf8mb4_unocode_ci)가 있다.

 

 

■ utf8 VS utf8mb4
utf8은 utf8mb3로 3바이트 가변 자료형이다.
대부분 언어는 utf8 자료형으로 저장하는데 문제가 없으나 최근에 나온 문자열 중 대표적으로 Emoji를 utf8에 저장하면 값이 소실되는 현상이 발생하여 나온 자료형이 utf8mb4로 4바이트 가변 자료형이다.
redmine, gitlab 등 거의 모든 app 들은 character set 으로 UTF-8 을 권장하고 있고 실제로도 UTF-8 을 사용하는게 좋습니다.
※ MySQL 은 UTF-8 은 3 byte 문자밖에 표시하지 못하므로 아래에서 설명할 utf8mb4 인코딩을 사용하는 것을 권장합니다.
 
 
■ 설정
MySQL 8.0 이상
MySQL 8 은 기본 character set 과 collation 이 utf8mb4과 utf8mb4_0900_ai_ci이므로 별도 설정 불필요
MySQL 5.5이상
MySQL 5.5 부터는 default-character-set 옵션이 제거되었고 character-set-server 만 설정해 주면 됩니다.
 
MySQL 은 UTF-8 구현을 대충 해서 3 Byte 밖에 표현을 못하는 문제가 있었는데 Emoji 가 활성화되면서 4 byte 로 표현해야 하는 UTF-8 문자들에 대한 요구 증가, 다른 DBMS 와는 달리 MySQL 은 utf8mb4 라는 4byte 를 표현하는 새로운 캐릭터 셋을 만들었으나 Emoji 나 기타 4 byte 로 인코딩하는 UTF-8 문자를 MySQL 에 저장하려면  utf8mb4 인코딩을 사용 필요. (MySQL 5.5.3 이상 필요)
utf8mb4 캐릭터 셋은 오직 MySQL 에만 해당되는 문제이고 다른 DBMS 는 아예 utf8mb4 라는 캐릭터 셋이 없으며 보통 인코딩을 UTF-8 로 설정하면 됩니다.
 
 
■ 확인 방법
MariaDB [(none)]> status
--------------
mysql  Ver 15.1 Distrib 10.2.12-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:        156
Current database:    
Current user:        root@localhost
SSL:            Not in use
Current pager:        stdout
Using outfile:        ''
Using delimiter:    ;
Server:            MariaDB
Server version:        10.2.12-MariaDB MariaDB Server
Protocol version:    10
Connection:        Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:        /tmp/mysql.sock
Uptime:            26 days 2 hours 55 min 17 sec

Threads: 7  Questions: 27968371  Slow queries: 0  Opens: 1387  Flush tables: 2  Open tables: 451  Queries per second avg: 12.392
--------------



MariaDB [(none)]> show variables like '%character%';
+--------------------------+------------------------+
| Variable_name            | Value                  |
+--------------------------+------------------------+
| character_set_client     | utf8                   |
| character_set_connection | utf8                   |
| character_set_database   | latin1                 |
| character_set_filesystem | binary                 |
| character_set_results    | utf8                   |
| character_set_server     | latin1                 |
| character_set_system     | utf8                   |
| character_sets_dir       | /mysql/share/charsets/ |
+--------------------------+------------------------+
8 rows in set (0.00 sec)

 

■ 변경 방법
MySQL 5.7 이하 character set 변경
ALTER DATABASE homestead CHARACTER SET = utf8mb4;
 
MySQL 8 에 새로 도입된 utf8mb4_0900_ai_ci Collation 을 사용하도록 변경할 수 있지만 collation 변경은 Primary key, unique constraint 등 여러 부분에 영향을 미치므로 주의해서 변경해야 한다.
MySQL 5.7 이상 character set 변경
ALTER DATABASE homestead CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;