Oracle Character Set 에 관하여
Oracle Character Set 에 관하여
DB를 처음 구성하는데있어 가장 먼저 결정 해야 하는 몇가지 요소가 있는데, DB Name (SID 명), Datafile들이 저장되는 경로 및 용량, 그리고 Charater Set 입니다.
캐릭터 셋은 한번 결정하고 나면 나중에 변경하기 굉장히 어렵기 때문에 처음 DB를 구성할때 신중히 결정 해야 합니다.
한국어를 지원하는 캐릭터 셋으로 대표적인 것이 두가지 있습니다.
KO16KSC5601 과 KO16MSWIN949
이 두가지 캐릭터 셋은 한글을 표현하는 EUC_KR의 캐릭터 셋입니다.
KO16KSC5601
한글 완성형 코드와 일치하며 일반적으로 많이 사용되는 2350자의 한글, 4888자의 한자와 히라카나, 카타카나, 그리고 영문 및 각종 기호들을 포함하고 있습니다.
KO16MSWIN949
Windows-949 Character Set은 MS사의 Windows Codepage 949번, 즉 한글 코드 페이지를 따른 코드셋입니다. 이는 완성형(KO16KSC5601)을 그대로 포함하고 있으며, 추가로 현대 한글 조합으로 표현 할 수 있는 모든 가짓수에 해당하는 8822자의 한글을 추가해 포함하고 있습니다. 그러니까 “Windows-949 Character Set은 KSC5601의 수퍼셋(SuperSet)”이 되며, 따라서 “KO16MSWIN949 또한 KO16KSC5601의 수퍼셋”이 됩니다. 즉, KO16MSWIN949가 KO16KSC5601를 포함하고 있다고 봐도 무방하며, 실제로 DB 마이그레이션 작업시 KO16KSC5601의 DB를 KO16MSWIN949 로 마이그레이션 할때는 크게 문제 되지 않습니다. 반면, 반대로 작업 시에는 문제가 발생 할수 있습니다. 역시 표기 할 수 있는 글자 수의 차이 때문입니다.
또 유니코드의 캐릭터 셋인 UTF-8과 AL32UTF8 도 한글을 지원 하는데 해당 캐릭터 셋은 한글 뿐만 아니라 모든 언어의 표기가 가능 하다.
UTF8 / AL32UTF8
UTF8 은 유니코드를 구현한 Character Set 중에 가변결이 인코딩 방식을 택하고 있는 Character Set입니다. 가변 길이를 위해 일종의 플래그 비트를 각 바이트마다 포함시켜야 하다보니, 한 글자를 표현하는데 필요한 바이트의 길이가 최대 3바이트(AL32UTF의 경우 6바이트)까지 늘어날 수 있습니다.
한글지원 Character Set 비교표
KO16KSC5601 | KO16MSWIN949 | UTF8 | AL32UTF8 | |
한글지원 상태 | 2350자 | 11172자 | 11172자 | 11172자 |
캐릭터셋/인코딩 | 한글완성형 | 한글조합형 | 8.1.6이전:Unicode 2.1
8.1.7이후:Unicode 3.0 |
9i R1 : Unicode 3.0
9i R2 : Unicode 3.1 10g R1 : Unicode 3.2 10g R2 : Unicode 4.0 |
한글바이트 | 2 Bytes | 2 Bytes | 3 Bytes | 3 Bytes |
지원버전 | 7.x 이상 | 8.0.6 이상 | 8.0이상 | 9i R1 이상 |
National Character Set | 불가능 | 불가능 | 가능 | 불가능 |
기타 |
National CharacterSet
National CharacterSet은 유니코드를 지원하지 않는 CharacterSet을 가진 데이터베이스에서 유니코드를 지원하기 위해 부가적으로 설정할 수 있는 CharacterSet입니다. 즉, 하나의 데이터베이스 인스턴스는 “CharacterSet”과 “National CharacterSet”을 가집니다. 처음 시스템 구축 당시와는 달리, 한글 이외의 다른 언어를 급히 저장해야 할 필요성이 있는 경우 National CharacterSet을 적절히 활용 할 수 있습니다. National CharacterSet이 가능한 CharacterSet은 단 두가지로, UTF8과 AL16UTF16(기본값)입니다. Nation CharacterSet을 사용하기 위해서는 특정 타입으로 테이블읠 컬럼 또는 PL/SQL 변수를 선언해야 합니다. CHAR와 VARCHAR2, CLOB에 대응되는 National CharacterSet 기반의 타입으로는 NCHAR, NVARCHAR2, NCLOB이 있습니다.
즉, KO16MSWIN949 데이터베이스에서 다음과 같이 테이블을 생성할 경우,
SQL> create table test_table (varchar_value VARCHAR2(2000) ,nvarchar_value NVARCHAR2(2000));
“varchar_value” 컬럼에는 KO16MSWIN949에 속하는 글자들만 저장 할 수 있는 반면, nvarchar_value 칼럼에는 유니코드에 속한 모든 글자들을 저장할 수 있습니다. 약간의 부가적인 코드가 필요할 뿐 실제 프로그래밍 방식은 거의 동일합니다.
CharacterSet 선택의 원칙
– 한글 지원을 위해서는 반드시 위의 네가지 CharacterSet 중에 하나를 선택해야 한다.
– 한국에서만 사용하는 시스템이라면 KO16MSWIN949를 선택한다.
– 한국어뿐 아니라 중국어, 일본어, 러시아어 등 다양한 언어로 된 데이터를 저장해야 한다면 UTF8, AL32UTF8을 선택한다. 인코딩 변환으로 한국어 기반의 CharacterSet에 비해 속도의 저하가 있다고 알려져 있음.
– 대부분이 한글이며, 일부 외국어가 필요하다면, 한국어 기반의 CharacterSet(KO16MSWIN949)을 사용하되, National CharacterSet을 이용한 칼럼에 외국어를 저장한다.
한글과 유니코드
기 존에 KSC5601에 문제점이 많았었는지 아니면 비 Latin 계열 문자의 설움인지 잘 모르지만, 한국은 처음부터 Unicode 표준 제정에 참가 하였습니다. 그 결과 Unicode에 독립적으로 한글만 표현할 수 있는 영역이 있을 정도입니다. 모든 표준이 그렇듯이 지금 Unicode 버전은 3.0입니다.
- Unicode 1.X : KSC5601에 정의되어 있는 글자만 표현가능
- Unicode 2.X : 새로운 한글 영역에 한글 정의
- Unicode 3.X : Unicode 2.X 이후 한글부분에서는 변화된 내용없음
Unicode에서 한글 자모음은 1100~11FF에 240글자가 정의되어 있으며, 이는 훈민정음 이후 없어진 모든 글자들을 포함하고 있습니다. 그리고 이 부분에는 한글의 초성/중성/종성이 모두 포함되어 있습니다.
Unicode 에서 한글 음절은 한글영역인 AC00~D7A3에 한글자모음으로 정의된 조합형 코드인 초성(19개) X 중성(21개) X 종성(27개+1개(받침 없음)) = 11172개의 완성형 한글이 가나다 순으로 정의되어 있으며, 이 방식은 자모 조합과 자모 분리가 용이하여 모든 현대 한글 및 한글 고어도 표현이 가능합니다.
Unicode 에서 한자는 CJK 상형문자 영역인 4E00~9FFF에 중국->일본->중국->한국 순으로 발음 기준으로 정의되어 있으며, CJK 상형문자 영역에 없는 한자는 CJK Compatibility Area adn Specials(F900~FA2D)에 별도 정의되어 있습니다.
Unicode CES
Unicode는 CCS이며 이런 Unicode를 표현하는 CES가 여러 개 존재합니다. 대표적인 UTF-8도 Unicode를 표현하는 CES중 하나입니다.
- UCS 2 : Unicode를 표현하는 CES에 표준이며 ISO/IEC10646의 CCS의 모든 문자를 2Bytes로 인코딩하여 검색, display, 구문해석에 용이한 특징이 있습니다.
- UTF-8 : ASCII 문자는 동일한 값에 1Byte로 표현, 유럽 및 기타 1Byte 글자는 2Bytes로 표현, 한국, 중국, 일본 한자 등은 3Bytes로 표현
이 때까지 언급한 한글 문제를 한번에 해결할 수 있는 방법은 없을까? 이러한 문제를 해결하기 위한 고심의 산물이 바로 Unicode입니다. 그렇다고 해서 Unicode가 만병통치약은 아님을 분명히 하고 시작을 합시다.
CCS와 CES
Coded Character Set(CCS)은 각각의 문자에 대하여 비트로 표현할 수 있는 정수값에 각각의 문자 하나씩을 할당하는 방식을 말하며 한국에서는 KSC-XXXX 또는 ISO-XXXX로 표현하는 Character Set이 대표적인 예입니다.
Character Encoding Schema(CES)는 각각의 문자에 대하여 16진수(Octet) 하나씩 할당하는 방식으로 CCS방식보다 많은 문자를 표현할 수 있다는 장점을 가지고 있습니다. 대표적인 CES는 UTF-8입니다.
Unicode
Any platform, any program, any language라는 슬로건으로 모든 문자에 대하여 고유 번호(Code)가 할당된 것을 말하며, 이는 모든 나라의 언어를 하나의 CCS로 정의해 놓았으며, 이러한 CCS를 표현하는 여러 개의 CES가 존재한다는 개념입니다.
- General Scripts Area(0000~1FFF) : Latin 계열 문자와 중동, 태국 문자 등의 할당 영역
- Symbol Area(2000~27BF) : 마침표, 느낌표와 같은 문자 기호와 숫자 등의 할당 영역
- CJK Phonetics and Symbols Area(3000~33FF) : 한국, 중국, 일본(CJK)에서 사용하는 음성/기호문자 할당영역
- CJK Ideographs Area(4E00~9FFF) : 한국, 중국, 일본(CJK)에서 사용하는 한자를 할당하는 영역
- Hangul Syllables Area(AC00~D7A3) : 한글 11172자를 할당하는 영역
- Surrogates Area(D800~DFFF) : 차후 사용목적으로 비어 있는 영역
- Private Use Area(E000~F8FF) : 사용자 및 공급자가 마음대로 사용할 수 있는 영역
- Compatibility Area and Specials (F900~FFFF) : 기존 Unicode안에 존재하는 값과 또 다른 값을 가지는 글자들을 할당하는 영역(일부 한자 포함)
NLS_LANG
오라클에서는 많은 환경변수 값을 사용하고 있습니다. 그렇지만 지금은 한글에 관한 이야기를 하고 있으므로 NLS_LANG만 가지고 설명합니다.
오 라클 DB 서버와 클라이언트간 NLS_LANG 값을 동일하게 하여 사용하는 경우가 99%가량입니다. 이렇게 사용하는 이유는 Oracle Client 프로그램을 이용하여 직접 오라클 DB에 접속하여 작업하는 경우가 대부분이기 때문입니다.
그러나 NLS_LANG 변수의 값은 오라클 DB 환경변수 값이 아나라, 사용자 자신이 속해 있는 환경을 오라클 DB 서버에 알려주는 역할을 하는 환경변수입니다.
NLS_LANG = [언어]_[영역].[캐릭터셋]
- 언어 : 현재 사용자가 사용하는 언어적 특성을 결정짓는 값
- 영역 : 현재 사용자가 위치한 영역의 특성을 결정짓는 값
- 캐릭터셋 : 현재 사용자의 시스템이 인식할 수 있는 캐릭터 셋의 값
만약 Windows Client에서 한국어 환경을 사용하는 경우 NLS_LANG 값을 ‘KOREAN_KOREA.KO16MSWIN949″로, 유닉스 클라이언트에서 한국어를 입출력한다면 ‘KOREAN_KOREA.KO16KSC5601’로 NLS_LANG를 설정 할 것입니다.
오라클 서버 CharacterSet과 클라이언트 CharacterSet을 동일하게 설정해야 하는 경우
앞서 이야기 했지만 NLS_LANG 값은 클라이언트 값이기 때문에 오라클 DB 서버와 동일하게 설정할 필요는 없지만 작업 및 그 동안 관습에 따라 오라클 DB서버와 NLS_LANG 변수 값을 동일하게 설정하는 경우가 많습니다. 그러나 오라클에서 아래에 나열한 작업이 필요할 경우 꼭 오라클 DB와 NLS_LANG 값을 동일하게 하는 것을 권장하고 있습니다.
- 데이터베이스로부터 데이터를 export 받을 때
- export 받은 데이터베이스와 같은 CharacterSet을 가진 DB로 export된 파일을 import 할 때
- 기타 다국어 지원 애플리케이션에서 목적에 따라 사용 할 때
NLS_LANG 관련 주요 변수
- NLS_TERRITORY : 영역 설정 – NLS_LANG 변수 값에 의해 자동 설정
* 설정 방법 예>
SQL> ALTER SESSION SET NLS_TERRITORY = 'KOREA';
- NLS_LANGUAGE : 언어 설정 – NLS_LANG 변수 값에 의해 자동 설정되는 초기화 변수
* 설정 방법 예>
SQL> ALTER SESSION SET NLS_LANGUATE = 'KOREAN';
- NLS_LANG : 언어, 영역, 캐릭터셋 설정 – 기본 값은 ‘AMERICAN_AMERICA.US7ASCII’
* 설정 방법 예>
OS 환경변수로 설정
- NLS_COMP : SQL에서의 비교 방식(<, >, =) 설정 – BINARY값으로 비교
* 설정 방법 예>
SQL> ALTER SESSION SET NLS_COMP = '';
- NLS_SORT : 문자열 정렬방식 설정 – NLS_LANGUAGE 값에 따라 결정
* 설정 방법 예>
SQL> ALTER SESSION SET NLS_SORT = 'KOREAN_M';
- NLS_TERRITORY 변수에 따라 그 값이 결정되는 변수
* NLS_CREDIT – 대차대조표 ‘대변’ 항목의 금액표기를 위한 기호. 보통 ‘공백’ 문자
* NLS_CURRENCY
* NLS_DATE_FORMAT
* NLS_DEBIT – 대차대조표 ‘차변’ 항목의 금액표기를 위한 기호. 보통 ‘마이너스’ 문자
* NLS_ISO_CURRENCY
* NLS_LIST_SEPARATOR – 숫자를 가로로 나열할 때 각 숫자를 구분하는 기호로. 한국의 경우 콤마.
* NLS_MOMETARY_CHARACTERS – 금액 표기시 금액을 읽기 쉽게 나누는 문자로. 한국에서는 3자리마다 “,”를 추가
* NLS_NUMERIC_CHARACTERS – 소수점 기호와 숫자 그룹핑을 위한 문자 설정. 우리나라에서는 ‘.,’ (dot와 comma).
* NLS_TIMESTAMP_FORMAT
* NLS_TIMESTAMP_TZ_FORMAT
* NLS_DUAL_CURRENCY – 유로화 변경 기간 동안의 혼란을 막기 위해 만들어진 매개변수. 9iR2와 그 이후로는 EU의 유로화 변경이 완료된 상태로 NLS_CURRENCY와 값이 동일하다. 다만 미래에 다른 지역에서도 통화기호의 변경이 일어나면 사용될 수 있음
- NLS_LANGUAGE 변수에 따라 그 값이 결정되는 변수
* NLS_DATE_LANGUAGE
* NLS_SORT
* NLS_
언어의 정렬
오라클 DB에서 한글을 사용하다보면 정렬에 관한 문제가 발생하는 경우가 있습니다. 특히 동양권(한국/일본) 언어에서는 자국에 원어이외에 한자를 사용하고 있으므로 인해 여러가지 문제가 발생하는 경우가 있습니다.
KO16KSC5601에서 한글 정렬
KO16KSC5601 에서는 한글 2350자의 바이너리 정렬 순서가 한글의 언어적 정렬 방식과 동일하다. 따라서, 단순히 Order by 명령만으로 정렬의 효과를 거둘 수 있습니다. 한자의 경우 한글 뒤에 한자의 음에 맞게 정렬이 됩니다. 이 것은 단지 한글 2350자들과 한자 4888자의 정렬일뿐이며, 나머지 글자들에 대해서는 입출력도 불가능합니다.
KO16MSWIN949에서 한글 정렬
KO16MSWIN949 는 KO16KSC5601에서 지원되지 않는 8822자의 한글을 추가적으로 지원한다는 점에서 KO16KSC5601의 대안으로 자주 이용되는 Character Set입니다. 하지만, 총 11172자의 한글의 바이트 코드가 한글의 언어적 정렬 순서와 불일치 합니다.
UTF8/AL32UTF8에서 한글 정렬
UTF8 데이터베이스의 경우, 한글만을 고려하면 별다른 정렬 옵션이 필요 없습니다. 왜냐하면 한글 11172자의 정렬 순서와 바이트 코드 정렬 순서가 일치하기 때문입니다.
그러나 한자를 포함한다면 한자->한글 식으로 정렬이 됩니다.
NLS_SORT
UTF8과 KO16MSWIN949에서는 원하는 형태의 정렬이 일어나지 않습니다. 이럴 때 NLS_SORT 값을 활용하여 원하는 형태의 정렬을 구현할 수 있습니다.
NLS_SORT=’KOREAN_M’
- 한글은 단순히 유니코드 바이트 정렬에 의존합니다.
- 모든 한글은 한자에 우선합니다.
- 한자는 발음 순서대로 정렬된다.
한마디로 KO16KSC5601에서 사용되던 정렬 방식으로 모든 한글과 한자를 정렬하겠다는 방법입니다.
NLS_SORT=’UNICODE_BINARY’
이 방법을 사용하면 각각의 문자에 대응하는 이진코드값을 기준으로 정렬됩니다. 이때는 한자->한글 순입니다. 즉, 한글과 한자를 사용하는 경우에는 NLS_SORT=’KOREAN_M’을 사용해야 합니다.
최신 댓글