2013년 7월 19일 금요일

오라클 계층형 쿼리 응용

나는 최근 오라클의 계층형 쿼리의 사용에 대한 질문을 받았다.



계층형 쿼리에 대해서 많은 개발자들이 어려워하는 것이 사실이다. 아래와 같은 엔터티가 존재할 때
 

많은 개발자들은 일반적으로 아래와 같은 데이터를 구하기 위해 SQL을 구사하는 것에는 큰 어려움이 없을 것이다.

SELECT  부서코드, 부서명, 상위부서코드
FROM   부서
START WITH 상위부서코드 IS NULL
CONNECT BY PRIOR 부서코드 = 상위부서코드


위의 SQL은 최상위 노드인 대표이사로부터 최하위 노드인 여러 지부까지 위의 그림처럼 계층적으로 출력할 때 사용한다. 그러나 조회 조건이 변화되면서 위의 그림처럼 표현하기 위해서는 어떻게 해야 할까?
즉 아래SQL 처럼 조회조건이 국내영업부(1120)’ 인데 전체 조직도를 출력해야 하는 것이다.

SELECT 부서코드, 부서명, 상위부서코드
FROM 부서
START WITH 부서코드 = '1120'
CONNECT BY PRIOR 부서코드 = 상위부서코드

 위와 같은 SQL을 실행하면 아래와 같은 결과가 출력될 것이다. 우리가 원하는 결과가 아니다.
 
우리가 원하는 결과를 얻기 위해서는 아래의 SQL처럼 최상위 노드를 찾아서 위에서 아래로 다시 찾아야 한다.
 이 예제에서는 최상위 노드가 하나여서 최상위 노드를 찾는 것이 의미가 없겠으나, 최상위 노드가 여러 개인 경우에는 반드시 필요한 절차이다.

SELECT 부서코드, 부서명, 상위부서코드
FROM   부서
START WITH 부서코드 = (SELECT 부서코드
                                              FROM  부서
                                             WHERE 상위부서코드 IS NULL
                                             START WITH 부서코드 = '1120'
                                             CONNECT BY PRIOR 상위부서코드 = 부서코드)
CONNECT BY PRIOR 부서코드 = 상위부서코드;

비록 아주 간단한 예제이지만, 많은 개발자들이 어려워하는 부분이라 포스팅 해본다.
이러한 것을 응용하면, 다양한 업무에서 유용하게 사용할 수 있을 것이다.
 
참고로 오라클의 계층형 쿼리에 대해서 몇 가지 설명하면,’
-       START WITH 절은 반복 탐색에 대한 시작지점을 설정하는 것이다. AND 절로 여러 개의 시작조건을 줄 수 있다.
-       CONNECT BY 절은 상위노드 또는 하위노드를 검색하는 조건을 기술하는 절로 역시 AND 조건으로 여러 개의 검색 조건을 줄 수 있다.
-       CONNECT BY 절에 쓰이는 PRIOR 키워드는 현재 읽어둔 레코드를 의미한다. 계층형 질의는 셀프 조인과 유사하다. A라는 테이블을 셀프 조인하는 경우 먼저 읽혀진 레코드와 조인 되어질 또 다른 A라는 테이블이 있을 때 먼저 읽혀진 쪽을 의미하는 키워드가 PRIOR인 것이다. 그러므로 ‘PRIOR 상위부서코드 = 부서코드로 기술하게 되면 상위노드로의 탐색이며, 반대로 ‘PRIOR 부서코드 = 상위부서코드로 기술하게 되면 하위노드로의 탐색이 된다.
-       그리고 계층형 질의문에서의 WHERE절은 탐색을 완료한 후에 데이터를 필터링하는 조건으로서 상황에 따라 불필요한 탐색을 줄 일려면 CONNECT BY 절에 기술하여 주는 것이 성능상 유리하다.
-       이외에 가상 컬럼인 LEVEL을 사용할 수 있으며, 계층형 쿼리에서만 지원되는 유용한 함수들이 존재한다.

아래는 테스트를위한 스크립트 이다.

DROP TABLE 부서 PURGE;
DROP TABLE 실적 PURGE;
CREATE TABLE 부서
( 부서코드 VARCHAR2(4) PRIMARY KEY
 ,부서명 VARCHAR2(30) NOT NULL
 ,상위부서코드 VARCHAR2(4) NULL);
 CREATE INDEX IDX_부서_01 ON 부서 (상위부서코드);

 CREATE TABLE 실적
 ( 년월 VARCHAR2(7) NOT NULL
  ,부서코드 VARCHAR2(4) NOT NULL
  ,금액 NUMBER(10) NOT NULL);
ALTER TABLE 실적 ADD CONSTRAINT PK_실적 PRIMARY KEY (년월, 부서코드);

 INSERT INTO 부서
 SELECT '1000', '대표이사', NULL FROM DUAL UNION ALL
 SELECT '1100', '영업1본부', '1000' FROM DUAL UNION ALL
 SELECT '1200', '영업2본부', '1000' FROM DUAL UNION ALL
 SELECT '1110', '국내영업1부', '1100' FROM DUAL UNION ALL
 SELECT '1120', '국내영업2부', '1100' FROM DUAL UNION ALL
 SELECT '1210', '해외영업1부', '1200' FROM DUAL UNION ALL
 SELECT '1220', '해외영업2부', '1200' FROM DUAL UNION ALL
 SELECT '1111', '수도권지부', '1110' FROM DUAL UNION ALL
 SELECT '1112', '강원지부', '1110' FROM DUAL UNION ALL
 SELECT '1121', '호남지부', '1120' FROM DUAL UNION ALL
 SELECT '1122', '경남지부', '1120' FROM DUAL;

 INSERT INTO 실적
 SELECT '2013.07', '1210', 1000 FROM DUAL UNION ALL
 SELECT '2013.07', '1220', 1000 FROM DUAL UNION ALL
 SELECT '2013.07', '1111', 1000 FROM DUAL UNION ALL
 SELECT '2013.07', '1112', 1000 FROM DUAL UNION ALL
 SELECT '2013.07', '1121', 1000 FROM DUAL UNION ALL
 SELECT '2013.07', '1122', 1000 FROM DUAL;

 COMMIT;

2013년 7월 6일 토요일

Oracle Architecture

오라클의 아키텍처를 그림으로 그려 보았다.
과거에 머리속에서 정리가 안될 때 이렇게 그림으로 그려놓았던 것인데, 블로그 활동을 시작하면서 올려본다.


Oracle 공유서버 vs 전용서버

아래 그림으로 Oracle의 공유서버와 전용서버의 방식 차이를 그려보았다.

위쪽 클라이언트에서 시작하는 것이 공유서버이고 아래쪽 클라이언트에서 시작하는것이 전용서버 방식이다.


Oracle 일반적인 wait event 목록

o buffer busy wait – 다른 세션에서 사용되고 있는 버퍼 캐쉬의 데이터 블록을 엑세스 하려고 할 때 발생
o read by other session - 다른 세션에서 버퍼 캐쉬로 적재하고 있는 블록을 읽으려고 할 때 발생
o control file parallel write – 세션이 모든 컨트롤 파일에 대한 I/O 요청이 완료되기를 대기할 때 발생
o db file parallel read – 하나 이상의 데이터 파일로부터 연속되지 않는 싱글블록들을 동시에 읽어 들일 때 발생
o db file parallel write – DBWR이 수정된 블록을 데이터파일에 기록할 때 발생
o db file scattered read – 멀티블록 I/O 요청이 완료되기를 대기하는 세션에 의해서 발생
o db file sequential read – 싱글블록 I/O 요청이 완료되기를 대기하는 세션에 의해 발생
o db file single write – DBWR에 의해 체크포인트가 발생하여, 데이터파일 헤더의 내용을 수정해야 할 때 발생
o direct path read – SGA내의 버퍼캐쉬를 거치지 않고 세션의 PGA로 직접 블록을 읽어 들일 때 발생
o direct path write – PGA내부의 버퍼로부터 데이터파일로 기록할 때 발생
o enqueue – 다른 세션이 incompatible 모드로 리소스에 대한 락을 소유하고 있는 경우, 해당 리소스에 대한 enqueue를 획득하려는 세션에서 발생
o free buffer waits – 버퍼캐쉬 내부에 데이터블록을 읽어 들이거나, CR블록을 생성하기 위한 프리버퍼를 찾지 못할 때 발생
o latch free – 다른 프로세스에 의해 사용되고 있는 래치를 획득하려고 할 때 발생
o library cache pin – 라이브러리 캐쉬에 있는 오브젝트를 변경하거나, 확인 하려고 할 때, 동시에 다른 세션에 의해 오브젝트가 변경되는 것을 방지하기 위해 반드시 pin을 획득 해야함, 이때 발생
o library cache lock – 라이브러리 캐쉬에 있는 오브젝트에 대한 동시 액세를 방지하거나, 상당히 긴 시간 동안 종속성을 관리하거나, 라이브러리 캐쉬로 오브젝트를 적재하려는 세션은 해당 오브젝트 handle에 대한 lock를 획득 해야함, 이때 발생
o log buffer space – 새로운 리도 레코드를 로그버퍼에 기록하려고 할 때 가용한 공간이 없으면 발생
o log file parallel write – LGWR 프로세스가 로그버퍼의 리두 레코드를 리두로그 파일에 기록 할 때 바발생
o log file sequential read – ARCH 프로세스가 온라인 리두로그 파일로 부터 블록을 읽어 들일 때 발생
o log file switch (archiving needed) - LGWR 프로세스가 리두로그 파일에 기록하는 속도를 ARCH 프로세스가 따라오지 못할 때 발생
o log file switch (checkpoint incomplete) - 로그파일에 대한 체크포인트 프로세스가 완료되지 않아서, 로그파일 스위치를 수행할 수 없을 때 발생
o log file switch completion - 로그파일 스위치가 완료되기를 대기할 때 발생
o log file sync - 유저 세션이 커밋이나 롤맥에 의해서 트랜잭션을 완료한 후 다음 처리를 수행하기 위해서는 세션의 리두 정보가 LGWR에 의해 리두로그 파일에 기록 되야 한다. LGWR 프로세스가 리두로그 파일에 기록하는 것을 완료할 때까지 해당 이벤트를 대기
o SQL*Net message from client – 세션이 클라이언트로 부터의 메시지를 대기 할 때 발생
o SQL*Net message to client – 클라이언트로 메시지를 전송 할 때 발생


*** RAC에서의 대기 이벤트들 ***

o global cache cr request – 리모트 인스턴스에 존재하는 버퍼의 CR블록을 읽으려는 세션은, 해당 CR블록이 로컬 인턴스로 전송될 때 까지 기다릴 때 발생
o buffer busy global cache – 세션이 리모드 인스턴스의 데이터 버퍼에 대하여 변경을 하려고 할 때 발생
o buffer busy global cr – 하나 이상의 세션들이 리모드 인스턴스의 CR블록을 순차적으로 기다릴 때 발생
o global cache busy – 세션이 SHARED모드로 소유하고 있는 버퍼에 대한 변경작업을 위해, 해당 버퍼를 CURRENT 모드로 변경할 때 발생
o global cache null to x – 세션이 블록을 변경하려고 할 때, 해당 블록은 로컬 캐쉬에 존재해야 하며, EXCLUSIVE모드로 소유해야 하지만, 버퍼가 로컬 캐쉬에 없고, 모드가 다른 경우 발생
o global cache null to s – 세션이 버퍼를 읽기 위해서는 해당 버퍼의 모드를 NULL모드에서 SHARED모드로 변경해야하지만, 버퍼가 로컬 캐쉬에 없고, 모드가 다른 경우 발생
o global cache s to x – 세션이 SHARED 모드로 소유하고 있는 버퍼를 EXCLUSIVE모드로 변경하려고 할 때 발생
o global cache open x – 세션이 로컬 인스턴스에 존재하지 않는 CURRENT 블록을 변경하려고 할 때 발생
o global cache open s – 세션이 버퍼캐쉬에 존재하는 블록을 처음으로 읽을 때 발생
o row cache lock – dictionary cache 에 존재하는 오프젝트의 정의를 보호하기 위해서는 row cache lock를 필요로 하며, 이 lock를 획득하려고 할 때 발생(library cache 와 dictionary cache 가 여러 인스턴스에 존재하는 RAC환경에서는 싱글 인스턴스 환경보다 더욱 심각한 문제를 유발 시킬 수 있음)

OWI - DFS_lock_handle

o DFS lock handle
    - DFS lock handle은 요청한 Global lock의 lock handle을 기다리고 있는 대기이벤트이다.이 lock handle은 global lock과 동일하다.
    - DFS lock handle 대기 이벤트 발생 원인
      * SV 락 경합 ( Sequence ( Cache + Order ) - RAC 에서 ) - 주로 발생하는 원인
      * CI 락 경합 ( Truncate 시 , 대상 테이블의 Dirty Buffer 가 Disk Write 로 인해 발생하는 대기 이벤트 )

    - OPS 나 RAC 환경에서 버퍼캐시 동기화를 제외한 row cache 나 libary cache의 동기화를 위해서 lock을 획득하는 과정에서 대기하는 이벤트
    - 여러 노드간에 시퀀스의 순서를 보장하려면 글로벌하게 lock을 획득해야하고 이 과정에서 DFS lock handle 대기가 발생하게 되는 것이다.
    - SV lock을 획득하는 과정에서 발생하는 DFS lock handle 대기이벤트의 P1, P2 값은 enq: SQ - contention 대기이벤트와 동일하다.
      (P1=mode+namespace, P2=object#) 따라서 P1 값으로부터 SV lock인지의 여부를 확인할 수 있고, P2 값을 통해 어떤 시퀀스에 대해 대기가 발생하는지 확인할 수 있다.
    - SV lock 경합 문제가 발생하는 경우의 해결책은 SQ lock의 경우와 동일하다.
       캐시 사이즈를 적절히 키워주는 것이 유일한 해결책이다.

빅데이터 아카데미 - 빅데이터 기술전문가 과정

한국데이터베이스 진흥원에서 빅데이터 아카데미를 운영하고 있다. 벌써 2기 수강생 모집이 마감되었다. 아래는 한국데이터베이스 진흥원에서 가져온 빅데이터 기술 전문가과정의 커리큘럼이다. 참고하시길.....

교육정보 빅데이터 기술 전문가
교육기간 : 94시간, 16
교육정보 빅데이터 기술 전문가 교육기간
구분
담당자
시간
비고
빅데이터 이해 및 트렌드 특강
빅데이터 기술 전문가
2시간
1일차
빅데이터 기술 전문가 Overview
심탁길 교수
5시간
1일차
빅데이터 기술 전문가
심탁길 교수
63시간
2일차 ~ 10일차
빅데이터 프로젝트
PJT Team
24시간
1(4시간) x 6
교육 대상
빅데이터 기술 전문가 교육대상
심사범위
선발기준
직무 기준
  • 개발자, DBA, SE(System Engineer)
  • 빅데이터 관련 직무자(빅데이터 처리 및 저장 관련 업무)
선수 조건
필수 조건
  • DB 및 프로그래밍 관련 업무 3(과장급) 이상의 중급 기술자
  • 관계형 데이터베이스 유경험자
  • Java Application, Java Script/Eclipse 사용 유경험자
  • 리눅스/유닉스 시스템 유경험자
우대 조건
  • 빅데이터 프로젝트 예정 인력
  • 데이터 분석 경험
  • 하둡(MapReduce, HDFS) 사용 유경험자
  • NoSQL 개념 이해 또는 경험자
  • 클라우드 서비스 및 인프라 사용/관리 유경험자
  • 분산파일 시스템 또는 분산 데이터베이스 유경험자
  • NoSQL, 캐싱기술 유경험자
교육 목표
·         빅데이터 처리 수요 증가에 따라 DB 분산 처리 및 관리에 대한 해법이 필요한 상황에서 빅데이터 기반의 분산처리 및 NoSQL 관리 기법을 학습하게 하여 빅데이터 관리 시스템 구축 비용 절감 및 효과적 빅데이터 전략 수립 방안 제시
·         빅데이터 핵심 기술인 하둡과 NoSQL의 논리적 구조와 물리적 구조에 대한 이해를 기반으로 하둡 관리 및 활용, MapReduce 프로그래밍, NoSQL(MongoDB) 관리 고급 기술을 습득하여 현업에 바로 적용할 수 있는 빅데이터 기술 전문가 양성
교육 내용 및 운영 계획
교육 내용 및 운영 계획
일차
단원명
(
학습모듈)
세부 내용
세세부 내용
중요도
소유
시간
1
공통
특강
빅데이터 이해

동향 분석
빅데이터 배경
2
빅데이터 기술 소개 및 동향
빅데이터 활용 사례 분석 및 적용 방법
Overview
빅데이터
기술 과정
소개
학습 모듈 및 학습 방법 소개 등
5
2
기본
빅데이터 아키텍처 및 개념
하둡 프로젝트 개요
빅데이터와 하둡
2
하둡의 역사
하둡 아키텍처 및 기본 개념
하둡 활용 사례 연구
전공
하둡 분산 파일
시스템
하둡 분산 파일시스템(HDFS) 개요
HDFS 아키텍처 및 특징
2
동작 원리 이해
파일 읽기/쓰기
전공
하둡 분산 파일시스템(HDFS) 응용
네임노드 설계 및 구성
2
하둡 환경 설정 최적화
HDFS 보안
Racw Awareness 구성
고가용 클러스터 구성
HDFS REST API 사용법
HDFS의 클러스터
운영 및 관리
HDFS 상태 점검
1
클러스터간 데이터 복제
클러스터 리밸런싱
네임노드 메타데이터 백업 및 복구
Mountable HDFS
3
전공
빅데이터 MapReduce
MapReduce
구조와 성능
MapReduce 아키텍처
7
MapReduce 처리 방식
Mapper, Reducer 기능 구현
Input/Output Format 입출력 제어
Combiner, Partitioner 중간 값 제어
4
전공
빅데이터 MapReduce 응용
Custom Input/Output Format 작성 방법
7
Custom Counter 작성 방법
압축 코덱을 이용한 입출력 제어 방법
다중 입출력 경로 제어 기능
비텍스트 데이터 처리 방법
응용 알고리즘(TF-IDF, PageRank) 사용 방법
5
전공
빅데이터 MapReduce
빅데이터 MapReduce 고급 분석
기계 학습 개요
7
Mahout 내용 분석 및 CLI 사용법
Clustering 라이브러리 개요
Classification 라이브러리 개요
Recommendation 라이브러리 개요
각 알고리즘 사용 및 활용 방법
6
전공
빅데이터
하둡
에코시스템
분산 수집 시스템(FLUME)
FLUME 개념 및 아키텍처 소개
7
SOURCE, SINK, DECORATOR 동작
FLUME CLI 및 웹콘솔 사용 방법
HDFS, NoSQL 연동 방법
FLUME 컴포넌트(Plugin) 개발 방법
7
전공
쿼리 분석 엔진(Hive/Pig)
HIVE 개념 및 아키텍처 소개
7
HIVE CLI 및 웹콘솔 사용 방법
Complex Query 제작 방법
Hadoop Streaming 연동
JDBC 기반 HIVE API 사용방법
8
전공
NoSQL(HBase, Cassandra)
NoSQL 개념 및 아키텍처 소개
7
NoSQL CLI 사용 방법
데이터 모델링, 저장 및 조회
API를 이용한 클러스터 제어
MapReduec를 이용한 데이터 처리
9
전공
빅데이터
하둡
에코시스템
데이터 통합
Sqoop 개념 및 아키텍처 소개
3
HDFS RDBMS간 데이터 Integration
MySQL데이터 HDFS Import
HDFS 데이터 MySQL Export
HDFS RDBMS간의 Internal 데이터전송
전공
웍플로우 관리
Oozie 개념 및 아키텍처 소개
4
Oozie MapReduce 작업 실행
Oozie HDFS 작업 실행
Oozie HDFS 작업 실행
Custom Java 작업 실행
웍플로우 제작 및 관리 방법
10
전공
응용 실습 과제: 추천 시스템 구축
영화 추천 시스템 개념 및 아키텍처
7
MovieLens 데이터셋 설명
추천 시스템 알고리즘 구현 방법 설명
Flume, MapReduce, Mahout, HBase를 이용한 영화 추천 시스템 실전 구축