Oracle Character Set 변환(4): 4.테스트 환경 구성
앞 글에 이어서 Oracle Character Set 변환 테스트 환경 구성 에 대해 살펴본다. Oracle 서버 환경 구성(세 개 instance, DB Link 생성), 테스트 테이블 생성, 테스트 데이터 생성 스크립트를 확인할 수 있다. 이 테스트 환경은 이후 Character Set 변환 과정에서 사용된다.
이전 글에서 이어지는 내용이다.
Oracle Character Set 변환(3): 3. Client 환경 구성(2)
4. Oracle Character Set 변환 테스트 환경 구성
4.1. Oracle DB 서버 환경 구성
Oracle Character Set 변환을 위한 테스트 환경을 Local PC(Windows)에 다음과 같이 구성하였음을 가정한다.
하나의 PC에 3개의 Oracle DB Instance를 설치했고, 각각의 구성은 다음과 같다.
환경 | SID | Server Character Set | Oracle Version | 테스트 User (Schema) |
US7ASCII 현행 DB | ORAUS7 | US7ASCII | 11.2.0.1.0 | LEG |
KO16MSWIN949 현행 DB | ORAMSWIN949 | KO16MSWIN949 | 11.2.0.1.0 | LEG |
AL32UTF8 목표 DB | ORAUTF | AL32UTF8 | 11.2.0.1.0 | LEG |
DB Link는 다음과 같이 구성하였다.
생성 SID | Target SID | 접속 User (Schema) | 용도 |
ORAMSWIN949 | ORAUS7 | LEG | KO16MSWIN949에서 US7ASCII 접근 및 변환 테스트 |
ORAUTF | ORAUS7 | LEG | AL32UTF8에서 US7ASCII 접근 및 변환 테스트 |
DB Link 생성 스크립트는 다음과 같다.
CREATE DATABASE LINK DL_US7 CONNECT TO leg IDENTIFIED BY leg USING '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORAUS7) ) )' ;
4.2. 테스트 테이블 구성
테스트를 위한 데이터 모델은 다음과 같다.
(테스트 목적상 정규화, 식별자 구성 등의 부가적인 내용은 모두 생략했으며, US7ASCII와 MSWIN949는 동일한 길이를 적용하고, AL32UTF8은 길이를 증가시킴)
위 데이터 모델은 서울시에서 공개한 <서울시 지하철호선별 역별 승하차 인원 정보> Data set에 테스트를 위한 두 개의 항목(참조설명, 참조이미지)을 추가한 구조이다.
출처: https://data.seoul.go.kr/dataList/OA-12252/S/1/datasetView.do
위 테스트 데이터 모델의 Schema를 생성하는 DDL은 다음과 같다.
-- 한글 2 byte 체계 스키마 생성(US7ASCII, MSWIN949) CREATE TABLE SUB_MON_STAT ( USE_MON VARCHAR2(8), LINE_NUM VARCHAR2(14), -- AL32UTF8: 50 SUB_STA_ID VARCHAR2(4), SUB_STA_NM VARCHAR2(20), -- AL32UTF8: 100 RIDE_PASGR_NUM NUMBER(10), ALIGHT_PASGR_NUM NUMBER(10), WORK_DT VARCHAR2(8), COMMT VARCHAR2(4000), REF_DES CLOB, REF_IMG BLOB ); -- 한글 3 byte 체계 스키마 생성(AL32UTF8) CREATE TABLE SUB_MON_STAT ( USE_MON VARCHAR2(8), LINE_NUM VARCHAR2(50), SUB_STA_ID VARCHAR2(4), SUB_STA_NM VARCHAR2(100), RIDE_PASGR_NUM NUMBER(10), ALIGHT_PASGR_NUM NUMBER(10), WORK_DT VARCHAR2(8), COMMT VARCHAR2(4000), REF_DES CLOB, REF_IMG BLOB );
AL32UTF8 에서는 한글 1글자에 3 byte가 필요하므로 두 컬럼의 길이를 충분히 길게 증가시켜 주었다.
엑셀 형식의 데이터 파일은 아래 github 경로에서 받을 수 있다.
* 엑셀 데이터파일: https://github.com/DAToolset/Oracle-CharacterSet-Conversion/raw/main/지하철역별 승하차인원_서울시오픈데이터_2013.xlsx
테이블에 데이터를 입력하는 DML은 아래 github 경로에서 받을 수 있다.
* DML: https://github.com/DAToolset/Oracle-CharacterSet-Conversion/raw/main/지하철역별 승하차인원_서울시오픈데이터_2013.sql
위 sql 파일을 일부 발췌하여 아래에 붙여 둔다.
INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT, COMMT, REF_DES, REF_IMG) VALUES('201301', '1호선', '0150', '서울역', 2199181, 1855268, '20130723', RPAD('서울역', 3000, '서울역'), RPAD('서울역', 3000, '서울역'), UTL_RAW.CAST_TO_RAW('12345')); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0151', '시청', 737005, 726892, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0152', '종각', 1542710, 1446464, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0153', '종로3가', 1159253, 1126995, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0154', '종로5가', 816307, 820769, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0155', '동대문', 446527, 512163, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0156', '신설동', 496150, 484583, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0157', '제기동', 587740, 601913, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0158', '청량리(지하)', 966341, 985741, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '1호선', '0159', '동묘앞', 240864, 252523, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0202', '을지로입구', 1610744, 1607133, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0203', '을지로3가', 539622, 559866, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0204', '을지로4가', 364217, 365994, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0205', '동대문역사문화공원', 435358, 508405, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0206', '신당', 407110, 438543, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0207', '상왕십리', 288629, 274519, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0208', '왕십리', 583444, 498091, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0209', '한양대', 262492, 286399, '20130723'); INSERT INTO SUB_MON_STAT(USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT) VALUES('201301', '2호선', '0210', '뚝섬', 402631, 420166, '20130723'); ...
지금까지 Oracle Character Set 변환을 위한 테스트 환경 구성과 구성 스크립트를 살펴보았다. 다음에는 이 테스트 환경에서 Character Set을 변환하는 여러가지 방법을 살펴보겠다. Oracle에서 권장하는 방법과 별도 구현이 필요한 방법으로 나누어 살펴볼 예정이다.