전문가칼럼

DBMS, DB 구축 절차, 빅데이터 기술 칼럼, 사례연구 및 세미나 자료를 소개합니다.

다국어 지원 데이터베이스(2) - 데이터베이스 구축하기

전문가칼럼
DBMS별 분류
Oracle
작성자
dataonair
작성일
2003-01-01 00:00
조회
12159





다국어 저장을 위한 데이터베이스 구축


엔코아 정보 컨설팅의 지용


지난 연재에서는 시장의 변화와 이에 따른 다국어 데이터베이스의 필요성에 대해 살펴보았다. 본 연재에서는 다국어 저장을 위해서 DBMS 주로 오라클 9i - 에서 어떤 것들이 지원되고 이것들을 이용함에 있어서 어떤 점들을 고려해 주어야 하는가에 대해서 살펴 보겠다.

▣ Character set 과 Font

이해의 편의를 위해서 기본적으로 알고 있어야 할 것들에 대해서 얘기하고 본격적인 이야기를 하도록 한다. 많은 사람들이 character set과 font의 대략적인 의미는 알고 있지만 정확한 의미는 모르는 것 같다. 이것들의 정확한 의미를 이해하면 character set을 바꾸는 것이 어떤 의미를 가지며 유니코드를 사용하면 왜 다국어를 저장할 수 있는가를 이해할 수 있게 된다.

컴퓨터는 이진수밖에 인식하지 못하므로 문자(symbol) A 를 A 로 인식하지 못하고 이것에 대응되는 이진수 값으로 인식할 수 밖에 없다. 따라서 어떤 문자(symbol)가 어떤 숫자(numeric value)에 대응된다는 것을 정의해 놓은 것이 필요하며, 그것이 character set이다. 그렇다면 문자(symbol)와 숫자(numeric value)의 관계만을 가지고 있으면 될 것인가 그렇지 않다. 이것을 사람들이 알 수 있도록 출력해주는 것이 필요하다. 이 역할을 font가 담당한다. 예를 들자면 문자(symbol) A 에 대한 숫자 값(numeric value)을 A 나 A 의 형태로 보여주고 출력할 수 있도록 해준다는 것이다.

그렇다면 Character set을 정한다는 것은 어떤 의미를 가질까 먼저 표현할 수 있는 문자의 종류를 정한다는 것을 의미한다. 한국어만, 일본어만 또는 유럽어들을 표현하고자 할 경우 Character set이 달라져야 한다는 것이다. 둘째로 어떤 문자(symbol)에 대응되는 숫자(numeric value)가 달라 진다는 것을 의미한다. Character set에서 표현할 수 있는 문자(symbol)의 수는 숫자(numeric value)의 길이를 얼마로 하느냐에 따라 좌우된다. Character set 마다 숫자(numeric value)의 길이가 다르기도 하고 동일한 길이지만 나타내는 문자(symbol)가 다르기도 하다.

Database는 설치된 O/S와는 별개로 저장될 데이터들이 가질 character set을 따로 정해준다. 이때 정해진 character set이 가지는 특성도 일반적인 character set의 경우와 똑같다. 어떤 character set을 정하느냐에 따라 저장할 수 있는 언어와 각 문자가 가지는 길이가 달라진다. 그렇다면 하나의 character set으로 여러 언어를 표현하는 방법은 없는가 아래에서 유니코드에 대해서 살펴보자.

▣ 유니코드(Unicode)

유니코드가 없었던 시기에는 한 데이터베이스에 중국어, 아랍어 등을 같이 저장할 수 없었기 때문에 해당언어를 지원하는 데이터베이스를 따로 구축했었다. 이렇게 할 경우 시스템 비용의 증가와 새로운 언어 추가 시의 비용, 전체 시스템의 통합된 정보를 조회의 어려움에 직면하게 되었고 하나의 character set으로 세계 각국의 언어를 표현할 수 있으면 좋겠다는 요구가 있어 유니코드가 탄생하게 되었다. 유니코드의 정의는 어떤 언어로 된 정보도 단일 character set으로 저장할 수 있는 국제적으로 부호화된 character set이다. 유니코드는 또한 platform, program, language에 관계없이 모든 character는 유일한 값을 가진다. 따라서 여러 나라 언어를 동시에 저장하고자 할 경우 유용하게 사용할 수 있다. 대표적으로 사용되는 유니코드로는 UTF-8, UCS-2, UTF16가 있으며 각각의 특징과 장단점을 도표로 나타내면 다음과 같다.

종류 인코딩 길이 subset 장점
UTF-8 8 bit 가변 길이
유럽어 : 1~2, 아시아어 : 3(대부분),

보충(supplementary)
character : 4 byte

ASCII 가변 길이므로 유럽어
저장시 공간을 덜
차지한다.

ASCII의 Superset이므로
ASCII에서 마이그레이션이
쉽다.
UCS-2 16 bit 고정 길이
유럽어 : 2 byte, 아시아어
: 2 byte,

보충(supplementary)
character : 지원 안함
아시아어를 저장시
공간을 덜 차지한다.

Java나 Microsoft 클라이
언트와 호환성이
좋다.
UTF16 16 bit 고정 길이
유럽어 : 2, 아시아어 : 2

보충(supplementary)
character : 4 byte
UCS-2 아시아어를 저장시
공간을 덜 차지한다.

Java나 Microsoft
클라이언트와 호환성이
좋다.

가변 길이는 언어마다 한글자가 차지하는 길이(byte)가 다르다는 것을 말하고, 고정 길이는 언어에 관계없이 한글자가 차지하는 길이는 동일하다는 것을 의미한다. 각 유니코드별 장점도 이러한 특성을 고려하면 쉽게 이해 할 수 있을 것이다. 이상으로 일반적인 얘기는 접고 오라클에서 유니코드를 이용하기 위해서는 어떻게 해야 하고 어떤 것들이 지원되는지를 살펴보자.

▣ 오라클의 유니코드 지원

오라클의 경우 V7에서는 유니코드 버전 1.1을 지원하는 AL24UTFFSS V7에서만 사용가능 도입하면서 유니코드를 지원하기 시작하였고 V8에서 유니코드 버전 2.0을 지원하는 UTF8이 도입되고 V9에서는 유니코드 버전 3.1을 지원하는 AL32UTF8 / AL16UTF16이 도입되어 유니코드를 지원하고 있다. 자세한 것은 아래 표를 보면 알 수 있다.

Character set 지원 버전 유니코드
인코딩
유니코드 버전 Database
character set
National
character set
AL24UTFFSS 7.2-8i UTF-8 1.1 지원 지원 안함
UTF8 8.0-9i UTF-8 8.0-8.1.6 : 2.1
8.1.7이후 : 3.0
지원 9i만 지원
UTFE 8.0-9i UTF-8 8.0-8.1.6 : 2.1
8.1.7이후 : 3.0
지원 지원 안함
AL32UTF8 9i UFT-8 9iR1 : 3.0
9iR2 : 3.1
지원 지원 안함
Al16UTF16 9i UFT-16 9iR1 : 3.0
9iR2 : 3.1
지원 안함 지원

▣ 다국어 지원을 위한 데이터베이스 구축 방안

지금까지 유니코드와 오라클에서 지원하는 유니코드에 대해서 살펴보았다. 다국어를 지원 데이터베이스를 생성하기 위해서 오라클에서 지원하는 유니코드를 어떻게 사용해야 할까 두 가지 방법이 있는데 하나는 유니코드를 데이터베이스 character set으로 지정해서 유니코드 데이터베이스를 구축하는 방법이고, 다른 하나는 데이터베이스 character set에 관계없이 NCHAR (National Character) 데이터타입을 이용하는 방법이다. 오라클 9i부터 NCHAR 데이터타입에 유니코드 character set을 지정할 수 있게 되었으므로 두 번째 방법은 9i부터 고려할 수 있는 방법이다.

방법 자체를 놓고 보면 아주 간단하다고 할 수 있다. 데이터베이스 생성시 데이터베이스 character set에 유니코드를 지정해서 char나 varchar2에 다국어를 저장하거나 데이터 베이스의 character set을 변경하지 않고 다국어를 저장할 컬럼을 NCHAR (National Character) 데이터타입으로 설정해서 다국어를 저장하면 된다. 그렇지만 방법을 결정함에 있어서 프로그래밍 환경, 마이그레이션의 용이성, 성능, 데이터 타입, 어플리케이션의 타입 등 많은 요소들을 고려해야 하기 때문에 결코 쉬운 일은 아니다.

이제부터 두 방법을 사용할 때 어떤 character set을 지정하는 것이 유리한가를 살펴보자. 유니코드 데이터베이스 구축하면서 지정 가능한 character set은 UTF8, AL32UTF8, UTFE이다. UTF8과 AL32UTF8은 유니코드에서 지정한 UTF-8과 거의 동일 특성을 가지고 있는데 UTF8의 경우는 보충(supplementary) character가 6byte를 차지한다는 점이 다르다. UTFE는 EBDIC platform을 위한 것이므로 일단 논외로 하겠다. 남은 UTF8과 AL32UTF8 중에서 UTF-8과 동일한 특성을 지닌 AL32UTF8을 사용할 것을 권장한다. AL32UTF8은 보충(supplementary) character가 4byte를 차지하므로 UTF8에 비해서 공간을 덜 차지하고 유니코드에서 정한 UTF-8과도 동일하기 유니코드3.1기준에 맞기 - 때문에 보충(supplementary) character를 처리하면서 data conversion의 부하가 발생하지 않기 때문이다.

NCHAR 데이터타입의 character set은 데이터베이스 생성시 NATIONAL CHARACTER SET에 지정된 값에 따르며 UTF8과 AL16UTF16을 지정할 수 있다. UTF8은 가변 길이기 때문에 스토리지를 절약할 수 있지만 처리시 스페이스를 붙이는 부하가 생기며, AL16UTF16은 고정 길이이기 때문에 처리시 스페이스를 붙이는 부하는 없지만 스토리지의 낭비를 초래할 수도 있다. 따라서 저장한 언어가 주로 어느 나라 언어인지 성능과 스토리지 절약 중 어떤 것에 중점을 둘 것인가를 고려해서 결정해야 한다.

여러 고려 요소들을 떠나서 가장 이상적인 방법은 AL32UTF8을 database character set으로 정하고 UTF8을 지원하는 언어로 프로그램을 개발해서 character set conversion이 없이 데이터가 오가는 것이다. 위에서 제시한 방법을 사용하여 데이터베이스를 구축 하면서 스키마 설계 시 어떤 점들을 고려해야 하는지 살펴보자.


▣ 스키마 설계시 고려해야 할 점

테이블 설계시 고려할 점은 어떤 것이 있을까 다국어를 저장하고자 할 경우 언어별로 컬럼을 달리해서 저장하는 방법, 특정 컬럼에 모두 저장하는 방법을 생각할 수 있다. 업무의 특성과 여러 요인을 고려하여 방법을 선택해야 겠지만 가장 이상적인 방법은 동일 컬럼에 모두 저장하는 방식이다. 그렇지만 이 경우 컬럼에 있는 데이터 만으로는 어느 언어인지 알 수 없으므로 언어정보를 관리할 컬럼을 추가해서 설계해야 한다. 이러한 언어정보 컬럼의 추가는 다음 연재에서 다루어질 Linguistic sort와도 밀접한 관계를 가지며 특정 언어로 된 데이터만을 검색하고자 하는 요구를 만족시킬 수 있는 유일한 방법이다.

데이터 타입을 정할 때는 어떤 것을 고려해야 할까 데이터 타입과 길이를 정할 때는 database character set에 가변 길이인 UTF8/AL32UTF8만 지정할 수 있다는 한계 점을 인식하고 접근하는 것이 좋다. V9 R2에서부터 문자데이터 타입의 경우 데이터의 길이를 기술함에 있어서 BYTE 또는 CHAR이라는 키워드를 사용하여 BYTE단위 또는 문자 단위로 기술 할 수가 있다. NCHAR 데이터 타입의 경우는 문자단위로 밖에 길이를 기술할 수 없다. 사용상의 주의 점은 데이터 타입과 길이 기술 방식 모두에 관계가 있으므로 각 길이 기술 방식에 대해서 알아보자. 간단한 사용 예를 보이면 다음과 같다.

 예) CREATE TABLE lang_test     (ename1 CHAR(4), ename2 CHAR(4 CHAR),  ename3 VARCHAR2(4), ename4 VARCHAR2(4 CHAR),  ename5 NCHAR(4),  ename7 NVARCHAR2(4) ) 

그렇다면 발생할 수 있는 경우의 수들에 대해서 길이를 4byte 또는 문자 4개로 주고 ‘a엔’ 이라는 데이터를 insert한 경우 length()와 lengthb()의 결과가 어떻게 나타나는지에 대해서 살펴보자.

데이터타입 CHAR VARCHAR2 NCHAR NVARCHAR2
기술방식 byte char byte char char Char
Character
set
UTF8 /
AL32UTF8
UTF8 /
AL32UTF8
UTF8 AL16UTF16 UTF8 AL16UTF16
길이 4 4 4 4 4 4 4 4
입력데이터 ‘a엔’ ‘a엔’ ‘a엔’ ‘a엔’ ‘a엔’ ‘a엔’ ‘a엔’ ‘a엔’
저장테이터 ‘a엔’ ‘a엔bb’ ‘a엔’ ‘a엔’ ‘a엔bb’ ‘a엔bb’ ‘a엔’ ‘a엔’
Length 2 4 2 2 4 4 4 2
Lengthb 4 6 4 4 6 8 4 4
테이블에
만들어지는 컬럼
길이
4 12-UTF8
16-
AL32UTF8
4 12-UTF8
16-AL32UTF8
12 8 12 8

여러 결과를 종합해 보면 다음과 같은 결론을 내릴 수 있다. CHAR 데이터타입의 경우 우리가 잘 알고 있듯이 길이의 선언 방식에 관계없이 기술된 길이보다 적으면 정해진 길이가 될 때까지 채운다. 이때 채우는 길이가 다른데 byte의 경우는 부족한 byte 만큼 스페이스를 채우고 문자 개수의 경우는 부족한 문자 개수만큼 스페이스를 채우며 스페이스가 차지하는 길이는 해당 character set의 최소 길이다. 좀더 거시적인 관점에서 얘기한다면 CHAR이므로 정해진 길이보다 모자란 부분은 스페이스로 채운다.

사용상의 주의 점에 대해서 알아보자. VARCHAR2/NVARCHAR2의 경우는 가변 길이이므로 발생할 데이터의 전체 길이에 맞게 길이를 잘 정하는 것 외에는 사용상에 주의 점은 없다. 그러나 고정 길이인 CHAR/NCHAR의 경우는 다르다. 길이를 문자 개수로 선언하거나 데이터 타입을 NCHAR로 선언한 경우 해당 컬럼내에서 언어에 따라서 길이가 달라지므로 값을 비교할 경우 길이가 다른 CHAR 타입을 비교할 때와 마찬가지로 스페이스 패딩이 일어난다. 따라서 CHAR 타입을 사용할 경우는 byte로 길이를 명시하고 NCHAR를 사용하고자 할 경우는 character set을 AL16UTF16으로 하여 저장 및 비교시 스페이스 패딩의 부하를 최소화 하여야 한다. 나아가서는 CHAR나 NCHAR 보다는 VARCHAR2, NVARCHAR2를 사용하여 스페이스 패딩 부하와 저장공간 낭비를 줄이는 것이 좋다.

▣ 클라이언트의 NLS_LANG 설정

지금까지 다국어 데이터베이스를 구축하기 위해서 서버쪽에서 어떻게 할 것인가에 대해서 살펴보았다. 그렇다면 클라이언트의 경우는 어떻게 해야 할 것인가 직접적인 방법을 언급하기 앞서 NLS_LANG이 하는 역할을 이해해야 한다. NLS_LANG에 Language, Territory, Characterset을 기술하게 된다. 이 중에서 Language는 오라클의 메시지나 요일이나 월등을 나타내는 언어를 의미하고 Territory는 통화나 숫자를 나타내는 형식, 주(week)를 계산하는 방식을 의미하며 Characterset은 클라이언트의 character set을 의미한다.

오라클은 NLS_LANG에 설정된 Characterset의 값이 클라이언트의 O/S 또는 클라이언트 프로그램의 character set설정에 맞게 설정되어 있는지 확인하지 않는다. 따라서 클라이언트의 character set이 오라클 데이터베이스와 다를 지라도 NLS_LANG이 데이터베이스의 character set과 동일하게 설정되어 있으면 character set conversion을 하지 않고 데이터를 저장하게 된다. 이렇게 되면 손상된 데이터가 저장되게 되므로 Characterset의 설정에 주의해야 한다.

따라서 NLS_LANG에 설정된 Characterset의 값은 클라이언트의 O/S 또는 클라이언트 프로그램의 character set에 맞게 설정을 해 주어야 한다. 그렇다면 클라이언트의 character set은 무엇에 의해서 결정될까 윈도우의 경우는 ACP (ANSI Code Page)에 의해서 결정되고 Unix의 경우는 터미널의 character set에 의해서 결정된다. 윈도우의 경우는 윈도우 화면에서와 도스 프롬프트에서의 ACP가 다른 경우 한글윈도우의 경우는 같다 - 가 있으므로 설정에 주의해야 한다. 윈도우 화면에서의 ACP는 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\ACP 라는 레지스트리 정보를 이용하면 알 수 있고, 도스 프롬프트에서는 chcp라는 명령을 통해서 알 수 있다. 이렇게 하면 코드값이 나오는데 한글 윈도우에서는 949이고 이는 오라클 character set 중에서 KO16MSWIN949에 해당된다. 값과 오라클 character set의 매핑에 대한 정보는 Globalization support를 참조하면 된다. 유닉스의 경우는 터미널의 환경정보를 이용하면 될것이다.

NLS_LANG의 Characterset을 설정함에 있어서 반드시 클라이언트의 O/S character set을 따라야 하는 것은 아니다. 클라이언트에 프로그램을 사용하여 데이터를 주고 받을 경우 이 프로그램이 UTF8을 지원한다면 O/S character set에 관계없이 UTF8으로 설정도 가능하다.

이상으로 다국어 저장을 위해서 데이터 베이스를 어떻게 구축할 것이며 고려 할 사항들은 어떤 것들이 있는지 알아보았다. 이 외에도 SQL에서 사용하면서 또는 프로그램밍 해나가면서 고려해야 할 사항들이 굉장히 많은데 이러한 것들은 globalization guide와 다른 매뉴얼들을 참조하기 바란다. 다음 연재에서는 linguistic index와 linguistic sort에 대해서 살펴보기로 하자.



제공 : DB포탈사이트 DBguide.net