Oracle2009. 7. 16. 11:40

클라이언트를 다운로드 받아봤으면 588MB나 됩니다.

전에도 말씀드렸듯이 VMS 클라이언트 용량이 150M 밖에 안되는데 DB접속만을 위해서 600M 가까이 되는 클라이언트 씨디를 일일이 배포해서 설치하는건 무리가 있어보입니다.

 

구글링을 하다 보니 설치 씨디로 SQL*NET을 설정하는 방법 말고 “Instant Client” 라는 오라클이 제공하는 40M 내외의 dll 모음들을 이용하는 방법을 발견했습니다.

VMS 클라이언트 프로그램 구동도 정상적으로 잘 됩니다. 혹시나 설치본 패키징 전이시면 참고하시기 바랍니다.

 

1.     http://www.oracle.com/technology/global/kr/tech/oci/instantclient/instantclient.html 에 가서 윈도우용 instant manager 를 받습니다.

윈도우용을 선택하고 다음 단계로 넘어가면 여러가지 패키징 버전에 있을텐데 Basic 을 받으시면 됩니다.

2.     압축을 풀면 instantclient 또는 instantclient_11_1과 같은 폴더가 있을텐데 이 폴더를 윈도우의 시스템변수로 설정합니다. 경로가 c:\instantclient_11_1 이라면

변수명 TNS_NAME 의 값으로 c:\instantclient_11_1 을 설정. 그리고 해당 경로를 Path 에도 추가합니다.

3.     2의 경로에 tnsnames.ora 파일을 만들고

PINK =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 255.255.255.255)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVICE_NAME = ORA9k)

    )

)

           를 추가합니다.

4.     PB Client 실행

 

패키징시에는 instant client 중 필요한 dll 몇개만을 PowerBuilder 클라이언트 프로그램에 함께 집어넣고 환경변수 TNS_NAME PATH에 에 PB 클라이언트의 경로를 잡아주면 될 것 같습니다.

tnsnames.ora 도 미리 만들어서 복사하면 될 것 같구요.
Posted by Julyus
Oracle2009. 7. 7. 10:44
SELECT  /* DSBIO4OS DSTAXCALZIROLIST51 */
/*+ push_suubq index(세금계산 세금계산_PK ) */
    세금계산.번호,
    세금계산,발행일자,
    세금계산,총액,
    세금계산,세액
    decode(세금계산.CHOICE1, '고객', TO_CHAR(세금계산.고객_번호),
                    세금계산.대리점_번호||TOCHAR(세금계산.기타업체_번호)) 고객번호,
    세금계산.고객상호
FROM 세금계산
WHERE 세금계산.번호
    in (select /*+ user_nl(지로지급, 세금계산_지로입금) */
                                    세금계산_지로집금.세금계산_번호
                from 지로지급,세금계산_지로집금
            where 세금계산_지로집금. 지로집금_번호 = 지르ㅗ집금.번호
              and 지로집금.일자 BETWEEN '&&1_FROM_DATE' AND '&&1_TO_DATE')
    AND EXISTS ( select 1 from 고객
                             where 세금계산.CHOICE1 = '고객'
                               and 고객.번호 = 세금계산.고객번호
                               and 고객.지로대상여부 = 'Y'
                               and 고객.청구사원_번호 = '&&1_SABUN' --19950113
                             union all
                                 select 1 FROM DUAL
                                 and 세금계산.CHOICE1 = '대리점');
집중사항
1. 데이타는 한번만 Select 해 온다. 죽어도 한번만 select 해 온다.
2. 범위를 일단 줄이는 쪽을 찾아라.
3. 조회할 테이블만 From절에 넣는다.
Posted by Julyus
Oracle2009. 7. 6. 16:03

////오라클의 딕셔너리뷰의table_name,column_name,data_type등등은 대문자로 저장되어있다.
//테이블 정의를 출력
select a.table_name table_name
 ,b.comments tab_comments
 ,c.column_id column_id
 ,c.column_name column_name
 ,d.comments col_comments
 ,c.data_type data_type
 ,decode(c.data_type,'CHAR'    ,to_char(c.data_length)
        ,'VARCHAR' ,to_char(c.data_length)
        ,'VARCHAR2',to_char(c.data_length)
        ,'NUMBER'  ,'('||to_char(c.data_precision)||','||to_char(c.data_scale)||')'
            )data_length
 ,decode(e.column_name,c.column_name,'Pk') pk_flag
 ,c.nullable nullable
 ,c.data_default data_default
 from user_tables a
 ,user_tab_comments b
 ,user_tab_columns c
 ,user_col_comments d
 ,( select f.table_name table_name
    ,f.column_name column_name
    from user_constraints e
    ,user_cons_columns f
   where e.constraint_name = f.constraint_name(+)
   and e.table_name = f.table_name(+)
   and e.constraint_type(+) = 'P'
 )e
where
//   a.table_name between 'GFC' and 'GFCZ'
  a.table_name like 'GFC%'
and a.table_name = b.table_name
and a.table_name = c.table_name
and a.table_name = d.table_name
and c.column_name= d.column_name
and c.table_name = e.table_name(+)
and c.column_name= e.column_name(+)
order by a.table_name,c.column_id
;


//테이블 프라이머리키 출력(1)
select f.table_name table_name
 ,f.constraint_name constraint_name
 ,f.position  position
 ,f.column_name column_name
 from user_constraints e
 ,user_cons_columns f
where f.table_name like 'GFC%'
and e.constraint_name = f.constraint_name(+)
and e.table_name = f.table_name(+)
and e.constraint_type(+) = 'P'
order by f.table_name,f.position
;

//테이블 프라이머리키 출력(2) <- 프라이머리키를 구성하는 칼람들을 한칼람으로 구성(키를 구성하는 칼람갯수는 최고 10개로 생각함)
select f.table_name table_name
 ,min(f.constraint_name) primary_name
 ,replace(rtrim(min(decode(f.position,1,f.column_name))||' '
 ||min(decode(f.position,2,f.column_name))||' '
 ||min(decode(f.position,3,f.column_name))||' '
 ||min(decode(f.position,4,f.column_name))||' '
 ||min(decode(f.position,5,f.column_name))||' '
 ||min(decode(f.position,6,f.column_name))||' '
 ||min(decode(f.position,7,f.column_name))||' '
 ||min(decode(f.position,8,f.column_name))||' '
 ||min(decode(f.position,9,f.column_name))||' '
 ||min(decode(f.position,10,f.column_name))),' ',',') column_name
 from user_constraints e
 ,user_cons_columns f
where f.table_name like 'GFC%'
and e.constraint_name = f.constraint_name(+)
and e.table_name = f.table_name(+)
and e.constraint_type(+) = 'P'
group by f.table_name
;

//테이블 인덱스키 출력(1)
select h.table_name
 ,h.index_name
 ,h.column_position
 ,h.column_name
 ,g.uniqueness
 from user_indexes g
 ,user_ind_columns h
where g.table_name like 'GFC%'
and g.index_name = h.index_name
order by h.table_name,g.uniqueness desc,h.index_name,h.column_position
;

//테이블 인덱스키 출력(2) <- 인덱스키를 구성하는 칼람들을 한칼람으로 구성(키를 구성하는 칼람갯수는 최고 10개로 생각함)
select h.table_name
 ,h.index_name
 ,replace(rtrim(min(decode(h.column_position,1,h.column_name))||' '
 ||min(decode(h.column_position,2,h.column_name))||' '
 ||min(decode(h.column_position,3,h.column_name))||' '
 ||min(decode(h.column_position,4,h.column_name))||' '
 ||min(decode(h.column_position,5,h.column_name))||' '
 ||min(decode(h.column_position,6,h.column_name))||' '
 ||min(decode(h.column_position,7,h.column_name))||' '
 ||min(decode(h.column_position,8,h.column_name))||' '
 ||min(decode(h.column_position,9,h.column_name))||' '
 ||min(decode(h.column_position,10,h.column_name))),' ',',') column_name 
 ,min(g.uniqueness) uniqueness
 from user_indexes g
 ,user_ind_columns h
where g.table_name like 'GFC%'
and g.index_name = h.index_name
group by h.table_name,h.index_name
order by h.table_name,uniqueness desc,h.index_name
;

/********************************************************************************************************
*****
 테이블 및 인덱스 정보
*********************************************************************************************************
****/

SELECT
 CASE WHEN ColumnName = '-' THEN TableName
   WHEN ColumnName = 'INDEX INFO' THEN ColumnName
   ELSE '-'
 END TableName
, CASE WHEN ColumnName = 'INDEX INFO' THEN '-'
   ELSE ColumnName
 END ColumnName
, ColumnComment
, CASE WHEN ColumnDataType = '-' THEN ''
   WHEN ColumnDataType = 'COLUMN DATATYPE' THEN ColumnDataType
   WHEN ColumnName = 'INDEX INFO' THEN ColumnDataType
   ELSE ColumnDataType + ' (' + CAST(ColumnDataLen AS VARCHAR(10)) + ')'
 END ColumnDataType
, IsIdentity, IsNullable
, Collation_name, Definition DefaultValue
FROM (
 SELECT
  ST.object_Id TableID
 , SC.column_id ColumnID
 , ST.name   TableName
 , SC.name   ColumnName
 , CCM.VALUE  ColumnComment
 , STY.name  ColumnDataType
 , SC.Max_length ColumnDataLen
 , CASE WHEN SC.is_identity = 1 THEN 'Y' ELSE 'N' END IsIdentity 
 , CASE WHEN SC.is_nullable = 1 THEN 'Y' ELSE 'N' END IsNullable 
 , SC.Collation_name
 , SD.Definition
 FROM sys.tables ST
  INNER JOIN sys.columns SC
   ON ST.object_id = SC.object_id
  INNER JOIN sys.types STY
   ON STY.system_type_id = SC.system_type_id
    AND STY.user_type_id = SC.user_type_id
  LEFT OUTER JOIN ( SELECT major_id, minor_id, VALUE
       FROM sys.extended_properties
       WHERE class = 1) CCM
   ON SC.object_id = CCM.major_id AND SC.column_id = CCM.minor_id
  LEFT OUTER JOIN (SELECT parent_object_id, parent_column_id, Definition FROM
sys.default_constraints) SD
   ON SC.object_id = SD.parent_object_id AND SC.column_id =
SD.parent_column_id
 UNION ALL
 SELECT
  object_id , -2 , name
 , '-' , '-' , '-' , 0 , '-' , '-' , '-' , '-'
 FROM sys.tables
 UNION ALL
 SELECT  object_id , 0 , '--'
 , 'COLUMN NAME' , 'DESCRIPTION' , 'COLUMN DATATYPE' ,
0 , 'ISIDENTITY' , 'ISNULLABLE' , 'COLLATION_NAME' ,'DEFAULT VALUE'
 FROM sys.tables
 UNION ALL 
 SELECT
  object_id, -1, OBJECT_NAME(object_id), 'INDEX INFO', NAME, type_desc , 0, idx_info, '-
' , '-' , '-'
 FROM ( SELECT D.object_id, IX.NAME, IX.type_desc COLLATE Korean_Wansung_CI_AS_KS AS
type_desc,
    CASE WHEN IX.is_unique = 1 THEN 'UNIQUE' + ' , ' ELSE '' END
   + CASE WHEN IX.is_primary_key = 1 THEN 'PK' + ' , ' ELSE '' END
   + ISNULL(MAX(CASE WHEN column_id = 1 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 2 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 3 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 4 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 5 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 6 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 8 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 9 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '')
   + ISNULL(MAX(CASE WHEN column_id = 10 THEN D.name + '' +
CASE WHEN IX.is_disabled = 0 THEN '( ASC )' ELSE '( DESC )' END + ' ' END ) , '') idx_info
   FROM (SELECT a.object_id, a.name, b.column_id, b.index_id FROM
sys.columns a INNER JOIN sys.index_columns b ON a.object_id = b.object_id AND a.column_id = b.column_id
AND OBJECTPROPERTY(a.object_id, 'IsUserTable') = 1 ) D
   INNER JOIN sys.indexes IX
    ON IX.object_id = D.object_id AND IX.index_id = D.index_id
   GROUP BY D.object_id, D.index_id, IX.NAME, IX.type_desc, IX.is_unique,
IX.is_primary_key, IX.is_disabled
 ) TIDX
) TBL
ORDER BY TableID, ColumnID

[출처] 테이블 명세서 출력|작성자 녀석



Posted by Julyus
Oracle2009. 6. 24. 20:15
오라클 (Oracle) ∵ Rule Based Optimizer

RBO 실행 우선 순위

1. ROWID에 의한 단일행 검색

2. Cluster-Join에 의한 단일행 실행

3. Unique-Key, Primary-Key를 사용한 Hash-Cluster Key에 의한 단일행 실행

4. Unique-Key, Primary-Key에 의한 단일행 검색

5. Cluster 조인

6. Hash-Cluster Key

7. 인덱스화된 Cluster-Key

8. 복합 인덱스

9. 단일 컬럼 인덱스

10. 인덱스가 생성된 컬럼에 대한 제한된 범위 검색

11. 인덱스가 생성된 컬럼에 대한 무제한 범위의 검색

12. 정렬-병합 조인

13. 인덱스가 생성된 컬럼에 대한 MAX, MIN

14. 인덱스가 생성된 컬럼에 대한 ORDER BY

15. Full-Table Scan



Oracle Optimizer #3

2009/04/20 09:15

Rule Base Optimizer

요즘에도 Oracle Database Application을 개발하다 보면 RBO(Rule Base Optimizer)를 사용 하는 경우가 만다. RBO를 사용한다는 이야기는 사전에 정의 되어 있는 순의에 따라서 Query 최적화를 한다는 이야기 이다.

같은 순위라면 Where절의 뒤부터, From절 뒤의 객체가 우선 순위를 갖는다. 한 Table에서 같은 순위의 인덱스가 있다면 가장 최근에 만들어진 인덱스를 사용한다.

그러나 1992년 Oracle 7에서 CBO가 지원되면서 CBO는 계속적인 신기능의 적용으로 발전해 온 반면, RBO는 더 이상의 기능 향상은 없으며, 향후는CBO만 지원될 계획이다

Oracle 7을 Oracle 10g로 Upgrade 하시면 가장 두려워 하는 부분이 RBO에서 CBO로 변경 되나는 것에 많은 분들이 두려워 하는 것이다. 그러나 대세가 CBO임 만큼 대세에 역류 해서는 안된다고 생각 한다.



http://cafe.naver.com/ilovedata/6


흑기사
날짜:2004-03-09 11:03:00
조회수:20


Posted by Julyus
Oracle2009. 6. 24. 17:25

※ Error관련 내장함수
- SQLCODE : 현재 발생한 오류에 따른 오류 코드를 반환
- SQLERRM : 오라클 오류 코드와 연결된 오류 메시지를 반환

 

 

※ 문자열 함수
ASCII <--> CHAR : ASCII, CHAR로 변환하기

 

CONCAT : 조합하기(||와 같은 역할)

 

SUBSTR : 자르기

 

SUBSTRB : 자르기

 

INITCAP : 첫글자만 대문자, 나머지글자는 소문자로 변환하기

 

UPPER / LOWER : 대문자/소문자로 변환하기

 

LPAD / RPAD : 왼쪽채우기/오른쪽채우기

 

LENGTH : 문자열의 길이 반환하기

 

LANGUAGE : KOREAN_LOREA.KO16KSC5601/AMERICAN_AMERICA.US7ASCII

 

REPLACE : 문자 대체하기

 

INSTR : 문자열에서 해당문자의 위치 반환하기

 

LTRIM / RTRIM : 문자열의 왼쪽/오른쪽 공백 버리기

 

TRANSLATE : 문자 대체하기(REPLACE와 같은 기능이나 스트링단위가 아닌 문자단위)

 

 


※ 수학 함수
ROUND : 반올림(해당자리수까지 보여주면서 반올림)

TRUNC : 버림값
MOD : 나눈후 나머지
CEIL : 무조건 올림

POWER : 승수값

GREATEST : 주어진 데이터중 최대값

LEAST : 주어진 데이터중 최소값

 

 


※ DATE 함수
- ADD_MONTHS : 지정된 날짜에 1달을 더함. 만일 결과가 나온 달이 현재 일수보다

  작은 일수를 갖고 있는 달로 변경되면 그 달의 마지막 날을 반환
- LAST_DAY : 주어진 달의 마지막 날을 반환
- MONTHS_BETWEEN : 두 날짜 사이의 개월수를 계산. 만일 두 날짜가 그 달의 마지막

  이라면 정수를 반환하고 그렇지 않으면 한달을 31로 계산한 분수값을 반환
- NEW_TIME : 사용자가 지정한 시간대에 대한 시간/날짜 값을 반환
- NEXT_DAY : 시작 날짜 다음에 지정된 요일이 처음으로 나오는 날짜를 반환
- ROUND : 월,년도,세기 등과 같이 선택한 날짜 파라미터를 반올림
- SYSDATE : 시스템 날짜와 시간을 DATE형식으로 반환
- TRUNC : 일,월 등과 같이 지정된 날짜 파라미터를 잘라냄
- date + number : date에 number만큼 후의 날짜를 보여줌(일수를 더함)
- date - number : date에 number만큼 전의 날짜를 보여줌(일수를 뺌)
- date1 - date2 : date1에서 date2까지의 총 일수를 보여줌(어떤날짜에서 다른날짜를 뺌)
- date1 + 숫자/24 : date1에서 시간을 더해 날짜를 보여줌(시간에 날짜를 더함)

MONTHS_BETWEEN : 날짜와 날짜 사이의 개월수를 반환

 

ADD_MONTHS : 날짜에 개월수를 더한 일자를 반환

 


NEXT_DAY : 해당일 다음에 오는 특정 요일을 반환

 


LAST_DAY : 지정한 달의 마지막날 반환

 


SYSTEM시간

 


※ 변환 함수
① TO_CHAR : DATE형, NUMBER형을 문자형으로 변환
② TO_NUMBER : 문자를 숫자형으로 변환
③ TO_DATE : 날자 형태의 문자열을 format에 맞게 날짜 형식으로 변환
     to_date('" + ls_refill_date2 + "235959','yyyymmddhh24miss') "

④ NUMBER와 DATE를 문자타입으로 변환
⑤ TO_TIMESTAMP : 문자열을 timestamp형식으로 변환
⑥ NVL : null일때 0을 보여줌
⑦ DECODE : default 반환, 디폴트가 없는 경우에는 null값을 반환. 반환하는 값은 최초의

    result와 같은 데이터타입(if..then..else기능을 구사하는 유용한 함수)
⑧ NULLIF : 결과값이 동일하면 null, 그렇지 않으면 첫번째 인자값 반환
⑨ NVL2 : 첫번째 인자값이 null이 아니면 두번째 인자값, null이면 세번째 인자값 반환

 

* 오라클의 환경변수 값 구하기
   select userenv('language') "lanugage",userenv('sessionid') "sessionid"

   from dual;

 

 

※ 그룹 함수
① COUNT : 행의 개수를 구함
② AVG : 평균을 구함
③ SUM : 합계를 구함
④ MIN : 최소값을 구함
⑤ MAX : 최대값을 구함
⑥ STDDEV : 표준편차를 구함
⑦ VARIALCE : 분산을 구함
⑧ VSIZE : 어떤값의 바이트수를 구함

 

 

 

 

** 변환함수/그룹함수는 예를 아직 못 올렸네요

     조만간 업데이트 할게요^-^

[출처] 오라클 함수|작성자 공부중

Posted by Julyus
Oracle2009. 5. 20. 14:06

4 년 전에 어느 손해보험 회사에서 차세대 프로젝트를 진행할 때의 일이다. 갑자기 본사에서 전화가 와서 손해보험사의 직원이 프로젝트에 참여 중인 사람들이 엔코아 컨설팅 직원이 맞느냐고 확인하더라는 것이다. 무슨 일인가해서 그쪽 업무 담당자에게 문의해보니, 오라클 DBMS를 사용하면서 계약일자, 사고발생일자 등의 날짜 타입의 속성을 왜 Varchar2(8)을 사용 안하고, Date 타입을 사용하라는 말에 어이가 없어 엔코아 직원들이 맞는지 물었다는 것이다.

 

필자가 왜 날짜 타입의 속성을 Varchar2(8)을 사용해야 하냐고 물으니,

 

1) 본인은 이제까지 프로젝트를 하면서 Date 타입을 사용한 적이 한번도 없었고
2) 대용량 데이터베이스 솔루션 1에 Date 타입보다 Varchar2(8)이 Like 연산자를 사용하는데 유리하다고 쓰여 있으니 그렇게 사용해야 한다고 하면서, 이번 프로젝트에 들어온 엔코아 컨설팅의 컨설턴트들이 사장님 말씀도 안 들으니 엔코아 직원이 맞느냐는 것이고,
3) 대한민국은 날짜 타입을 보여주는 방식이 YYYY/MM/DD인데 오라클의 NLS Date 타입이 이것과 달라 날짜를 보여주기 위해서는 Format을 바꿔야 하므로, 이것이 코딩하는데 시간을 많이 잡아먹는다는 것이다.

 

이 글을 읽는 분들 중에도 위 답변이 당연한 거 아닌가라고 말할지 모르겠다. 그렇다면 이 이야기도 어떤가?

 

이전 어느 모은행의 프로젝트에서 중요 업무는 메인프레임 기반에서 계층형 DBMS를 사용하고, 일부 업무를 UNIX에 오라클을 사용했다. 어느 날 본사 직원이 데이터 타입이 안 맞는 속성을 발췌해 왔는데 A4 용지로 약 30장에 달하는 속성들이 데이터 타입이 맞지 않는 경우가 있었다. 사연인 즉, PMO 그룹에서 이 은행의 데이터 표준은 메인프레임의 계층형 DBMS가 표준이니 그것에 맞추라고 한 것 때문이었다. PMO 말을 잘 들은 일부 직원들은 오라클을 사용함에도 불구하고 데이터 타입을 계층형 DBMS의 데이터 타입을 사용했고, 반면 오라클을 잘 아는 일부 직원들은 오라클에서 제공하는 데이터 타입을 사용했기 때문에 이러한 일이 발생했던 것이다.

 

데이터 무결성이 업무 효율성으로 이어진다
관 계형 데이터베이스의 장점 중 하나는 무결성(Integrity)이라는 개념이다. 무결성이란 관계형 연산자를 이용해 데이터가 입력(Insert), 수정(Update), 삭제(Delete), 조회(Select)될 때 데이터 값이 정확성과 일관성을 가져야 되는 업무 규칙(Business Rule)을 말한다.

 

이러한 무결성 가운데 하나가 속성 무결성 또는 도메인(Domain) 무결성이라는 것이다. 도메인이란 관계형 테이블에 표현되는 속성이 취할 수 있는 값의 집합을 말한다. 예들 들어, 고객명 속성의 데이터 타입을 Varchar2(30)으로 정했다면, 30자리 내에서 문자 값으로 들어올 수 있는 모든 값의 집합이 고객명의 도메인인 것이고, 계약 일자를 Date 타입으로 잡았다면 이 세상에 존재하는 모든 날짜 값의 집합이 계약일자의 도메인인 것이다. 만약에 우리가 계약일자를 Varchar2(8)로 잡았다면 엄밀히 말해서 이는 8자리 내에서 모든 문자 값의 집합이 이 계약일자의 도메인인 것이다.

 

이러한 개념은 관계형 데이터베이스 이전에는 없던 개념으로 과거에는 모든 데이터의 무결성을 프로그램 로직으로만 해결했다. 프로그램 로직으로 이러한 것을 체크하다 보니 데이터 값이 안 맞아 고생한 경우가 가끔 있었을 것이다. E.F.CODD 박사는 이러한 문제를 해결하고자 DBMS 내에 무결성이라는 개념을 도입해 데이터의 정확성과 일관성을 유지하려고 했던 것이다.

 

도메인 무결성을 반드시 지켜야 하는 이유를 살펴보면,

 

첫째, 우리는 도메인을 보고서 의사 결정을 한다는 것이다.
다 시 말하지만 도메인은 속성이 취할 수 있는 모든 값의 집합이라고 했다. 예들 들어, 계약상태라는 속성이 취할 수 있는 값의 집합은 신청, 취소, 유지, 종결의 네 가지가 있다고 할 때, 이 네 가지가 이 속성의 도메인인 것이다. 계약일자는 업무 규칙에서 모든 날짜 집합이 도메인이 될 수 있지만, 계약상태는 업무 규칙에 의거해 이 네 가지 중에 하나만 선택할 수 있는 것이다. 보통 이런 코드 속성은 코드 도메인을 갖는다고 표현하다. 우리는 계약상태의 네 가지 도메인을 보고서 의사 결정을 할 수 있는 것이다.

 

둘째, 도메인의 중요성은 같은 도메인끼리 비교가 가능하다는 것이다.
현 실 세계에서 예들 들어 보면 형과 아우를 결정할 때 우리는 서로의 나이를 비교해서 결정한다. 나이와 고향을 비교할 수는 없다. 일본사람, 한국사람, 미국사람을 판단할 때는 국적을 가지고 비교하지 다른 어떤 속성으로 비교하지는 않을 것이다. 데이터 모델링에서 고객 테이블에서는 고객번호 속성을 Varchar2(10)로 하고, 계약 테이블에는 고객번호를 Number(10)로 한다면, 이는 비록 값이 같을지라도 DBMS는 다른 도메인으로 인식한다. 이런 경우, DBMS가 비교를 하기 위해서는 같은 도메인이어야 하기 때문에 두 개의 테이블을 조인하는 경우 한 쪽의 도메인(데이터 타입)을 내부에서 바꾼다. 이렇게 되는 경우 잘못하면 DBMS의 옵티마이져가 ACCESS PATH를 잃어버려 FULL TABLE SCAN을 하게 되어 수행속도상에 엄청난 비효율을 유발할 수 있는 것이다.
 

글 : 장희식_엔코아정보컨설팅 기술상무
 금융(은행, 증권, 보험, 종금, 리스 등), 공공, 유통 등 많은 프로젝트에서 데이터 모델링 컨설턴트로써 역할을 수행해 왔으며, 정보 시스템 구현에 있어서 가장 중요한 업무 분석을 어떻게 하면 잘 할 수 있을까를 늘 고민하면서, 이러한 문제를 해결하는데 미력하나마 공헌하고자 데이터 모델링 책을 집필 중이다. 많은 프로젝트에서 고생 하고 있는 선배, 동료, 후배들에게 조금이나마 기여할 수 있는 컨설턴트가 되기를 기원하며 오늘도 프로젝트를 수행중이다.

 

출처: http://www.kdug.kr/blog/129

Posted by Julyus
Oracle2009. 4. 30. 14:14
Posted by Julyus