문자집합은 컴퓨터에서 문자를 표현하는 데 사용되는 일련의 데이터입니다. 'A'라는 문자를 컴퓨터에서 표현할 때 어떤 데이터를 사용할지는 문자집합에 달려 있습니다.
'가'는 UTF-8에서 3바이트로 표현됩니다: 0xEA 0xB0 0x80
'가'는 EUC-KR에서 2바이트로 표현됩니다: 0xB0 0xA1
문자집합마다 지원하는 언어의 범위가 다를 수 있습니다.
MySQL에서 지원하는 문자집합을 보려면 아래와 같이 명령할 수 있습니다.
mysql> show character set;
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| binary | Binary pseudo charset | binary | 1 |
| cp1250 | Windows Central European | cp1250_general_ci | 1 |
| cp1251 | Windows Cyrillic | cp1251_general_ci | 1 |
| cp1256 | Windows Arabic | cp1256_general_ci | 1 |
| cp1257 | Windows Baltic | cp1257_general_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
| cp852 | DOS Central European | cp852_general_ci | 1 |
| cp866 | DOS Russian | cp866_general_ci | 1 |
| cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |
| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
...
그렇다면 완전한 한글만 저장하려면 어떻게 해야할까요?
첫 번째 방법으로는 완전한 문자만 지원하는 문자집합이 있는지 궁금했습니다. 혹시 존재한다면, 문자집합만 바꾸는 것으로 해결할 수도 있다고 생각했습니다. 한글을 지원하는 대표적인 문자집합인 eucKR을 확인해 보았으나, 이 문자집합 역시 'ㅇ'과 같은 불완전한 한글도 지원했습니다.
그래서 결국 문자집합을 변경하는 방법으로 구현하기는 어렵다고 생각했습니다.
두 번째 방법으로 트리거를 생각했습니다. 트리거는 데이터베이스에서 제공하는 기능으로 삽입/삭제와 같은 이벤트 발생 시 할 일을 정의해 놓을 수 있습니다.
krtext 테이블에서 insert 이벤트 발생 시 트리거가 실행됩니다.
각 행에 대해 정규식으로 완전한 한글로 구성되어 있는지 검사합니다.
완전한 한글이 아니라면, 에러를 발생시켜 삽입 작업을 중단합니다.
DELIMITER $$
CREATE TRIGGER CheckValidKorean
BEFORE INSERT ON krtext
FOR EACH ROW
BEGIN
IF NOT (NEW.txt REGEXP '^[가-힣]+$') THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid Korean characters';
END IF;
END$$
DELIMITER ;
삽입이 실패하고, 제가 정의한 에러가 발생한것을 확인할 수 있습니다.
mysql> insert into krtext (txt) values ('아');
Query OK, 1 row affected (0.01 sec)
mysql> insert into krtext (txt) values ('ㅇ');
ERROR 1644 (45000): Invalid Korean characters
UTF-8 VS eucKR
eucKR이 한글 전문적으로 지원하는 대표적인 문자집합이라고 해서 어떤 상황에 사용해야 할지 궁금해서 비교해보았습니다.
UTF-8:
유니코드를 사용해 전 세계의 모든 문자를 표현할 수 있습니다.
가변 길이로 인코딩되어 최소 1바이트, 최대 4바이트로 표현합니다.
영문은 1바이트이고, 한글의 경우에는 3바이트입니다.
MySQL에서는 utf8mb4가 완전한 구현입니다. utf8을 사용하면 이모지와 같은 4바이트의 문자들을 표현할 수 없습니다.