태그 Archives: UTF8

유니코드 문서의 Byte Order Mark

보통 일반적으로 접하게 되는 문서는 ASCII 혹은 UTF8 문서 이다.

다만 문서중 UTF8 의 경우 일반 UTF8, UTF8 (BOM) 문서가 있다.

 

UTF8 (BOM)의 경우 윈도우 메모장에서 UTF8문서를 생성할 경우 파일의 첫부분에 삽입되게 되며 “EF BB BF” 값을 가진다.

또란 실제 삽입되어 있지만 메모장으로 파일을 불러들였을때에는 보이지 않도록 처리가 되어 있다.

 

즉 있는지 없는지 확인이 안되고 오류를 발생시키기 때문에 문제가 된다.

 

아래 처럼 utf8 에서는 ea b0 80 = “가” 을 나타낸다.

 

일반 ASCII 파일 혹은 일반(리눅스에서 생성한) UTF8 문서를 확인해보면 아래와 같다. # = 23 | 가 = ea b0 80 | \n(엔터) = 0a

 

윈도우 메모장으로 생성\하여 BOM 이 삽입된 파일은 다음과 같다.  utf8(bom) = ef bb bf | \r\n(윈도우엔터) = 0d 0a

 

위와 같은 이유로 윈도우에 mysql 을 설치 하고 메모장으로 my.ini 파일을 수정한뒤에 저장 하면 UTF-8(BOM) 으로 저장 되어 mysql 서비스 시작이 되지 않는다.

메모장으로 하더라도 “다른 이름으로 저장” 시 인코딩을 ANSI 으로 설정하고 저장 기존 파일명과 같게 저장 하는 방법이 있다. (근데 사람은 같은 실수를 반복하기 때문에…)

2021-01-14_113358

윈도우 내에서의 문서 작업은 메모장이 아닌 BOM 없이 생성 가능한 에디터를 사용하는 습관을 들여야 할것 같다 ‘ㅅ’a

무료 툴 : AcroEDIT

 

PS. UTF16 의 경우 UTF16BE , UTF16LE 두가지 형식이 존재하며 두가지 모두 Byte Order Mark 를 가지고 있다. 아래표 참조 ‘ㅅ’a

 Byte
Order
Mark
문자 길이HEX 코드
( # )
HEX 코드
( 가 )
HEX 코드
( 핣 )
UTF16BEFE FF4 Byte23 00AC 00D8 A9
UTF16LEFF FE4 Byte00 23AC 00D8 A9
UTF8(BOM)EF BB BF1 ~ 3 Byte23EA B0 80ED 95 A3
UTF8-1 ~ 3 Byte23EA B0 80ED 95 A3
ASCII1 Byte23표현 불가
UTF32BEFE FF 00 008 Byte23 00 00 00AC 00 00 00D8 A9 00 00
UTF32LE00 00 FF FE8 Byte00 00 00 2300 00 AC 0000 00 D8 A9

 

데이터베이스 마이그레이션

EUC-KR 에서 UTF-8 로 DB마이그레이션을 진행할때 캐릭터셋 전환에 따라 일부 문자가 유실 되거나 깨지게 되어 dump된 파일의 복구가 곤란한 경우가 발생하였다.

sql은 복원중 에러가 발생을 할경우 하위 내용을 복구를 하지 않기 때문에..
이러한 경우 보통 sql 파일을 하나하나 수정해가면서 다시 부어넣는 짓을 해야한다 =_=a

DB용량이 작다면 하나하나 수정해줄수 있지만 100M단위를 넘어가는 파일을 변경하긴 어렵다.
때문에 테이블 생성정보와 데이터를 따로 따로 백업을 하고 먼저 테이블을 생성한뒤에 복구하는 방법을 쓰기로 하고 스크립트를 작성하였다.

 

위와 같이 원본서버에서 백업을 할때 데이터를 분리 한뒤에 iconv를 이용해서 캐릭터셋 치환을 하고 캐릭터셋 선언을 바꾸어 준다.

이중 -c 옵션은 에러가 나는 문자열을 제외하고 치환하는 옵션이다.
가급적 에러가 나지 않는게 좋겠지만 ‘ㅅ’…

 

새로운 데이터 베이스에 먼저 테이블 복원을 한다.

아래와 같은 스크립트작성을 한 뒤에 실행한다.

IFS 를 통해 구분자를 엔터(\n) 으로 지정한뒤 for 문을 돌려 한줄한줄 복원을 시도 하고
에러가나는 구분은 error_query.sql 파일로 별도 저장을 한다.

추후 error_query.sql 파일을 분석하여 쿼리문을 완성 시켜 재 복원을 하거나… 버리거나.. 할수 있겠다.

 

테이블 복원중 VARCHAR(255) UTF8 is too long for key, but max length is 1000 bytes 가 나오는 경우가 발생할수 있다.
key로 사용되는 컬럼의 길이가 1000byte를 넘어가면 안된다는 메세지 이다.
(Mysql에서 UTF8의 경우 문자당 3byte 를 사용한다 – utf8mb4 = 4Byte 를 쓴다..)

이경우 key로 사용되는 컬럼의 varchar 값을 최대치인 333이하를 쓰도록 한다.
일반적으로 2개 이상의 컬럼은 하나의 키로 사용하는 부분에서 에러가 난다. 그때는 사용된 컬럼의 합이 333 이하여야 하겠다.

utf8mb4의 경우에는 200 이하로 해야겠고.. 그래서 대략 아래와 같이… 큰 varchar 컬럼을 앞95자까지 인식하도록 하게 한다.
컬럼A varchar(255)
컬럼B varchar(255)
KEY 키명 (컬럼A(95),컬럼B(95)),