그럼 먼저 파티션을 도입하게 된 배경과 파티션의 기본적인 역할에 대해 알아보자.
Partitioning은 대용량의 Table을 Partition이라는 보다 작은 단위로 나눔으로써 데이터 액세스 작업의 성능 향상을 유도하고 데이터 관리를 보다 수월하게 하고자 하는 개념이다.
물론 무조건 파티션만 한다고 파티션이 가지고 있는 이점을 모두 취할 수 있는 것은 아니다. 잘못된 인덱스가 오히려 처리 속도에 나쁜 영향을 미치듯이 파티션 키를 어떻게 구성하느냐에 따라 많은 비효율을 초래할 수도 있기 때문에 파티션 키의 선정은 다음과 같은 기준에 따라 전략적인 관점의 세심한 판단이 요구된다.
첫째, 성능향상을 위하여 어떤 부분을 고려 해야 하는가?
데이터를 처리하는 방법은 크게 인덱스를 경유하는 Random Access 방법과 인덱스를 경유하지 않고 전체 데이터를 Scan 하는 두 가지 방법이 있다. 데이터의 분포도가 좋아서 인덱스를 사용할 수 있는 상황이라면 문제될 것이 없지만 분포도가 나빠서 인덱스를 사용할 수 없다면 인덱스를 사용하지 않고도 필요한 부분만 액세스를 할 수 있도록 Partitioning이 이루어져야 한다. 또한 결합 파티션키인 경우에는 구성 대상 컬럼의 선정 및 컬럼들간의 결합순서도 고려하여야 한다.
즉, 액세스 유형에 따라 Partitioning이 이루어질 수 있도록 파티션 Key를 선정해야 한다.
둘째, 데이터 관리의 용이성을 위하여 어떤 부분을 고려 해야 하는가?
이력을 관리하는 데이터는 데이터 관리 전략 및 업무규칙에 따라 그 수명이 다하게 되면, 별도의 저장장치에 기록되고 데이터베이스에서 삭제되게 된다. 이력 데이터는 활용가치에 따라 생성주기와 소멸주기가 결정되게 되고 그 주기에 따라 데이터베이스를 정리해야만 한다. 만약 사용자가 사용하지 않는 데이터를 삭제해야 되는데 그 데이터가 여러 파티션에 분산되어 있다면 , 그 데이터를 추출하여 삭제하는데 많은 노력과 시간이 필요할 것이다. 하지만 파티션이 데이터의 생성주기 또는 소멸주기와 일치한다면 파티션을 대상으로 작업이 이루어 지므로 관리가 용이하게 된다.
즉, 이력 데이터의 경우에는 생성주기 또는 소멸주기가 파티션과 일치하여야 한다.
그럼 이동통신회사의 개념적인 데이터 모델을 가지고 집합 유형별로 Partitioned Key를 선정하는 사례를 알아보자.
개략적으로 테이블별 집합에 대해서 알아보자.
고객 테이블은 모든 고객에 대한 개체집합으로서 고객유형이라는 서브타입이 존재한다.
가입계약 테이블은 한번이라도 가입계약을 맺은 고객의 가입계약ID에 대한 개체집합이다. 즉, 가입계약별 최근 데이터만 관리한다.
가입계약상태 테이블은 모든 가입계약에 대해서 발생하는 이벤트(가입계약상태)에 대한 정보를 관리하는 행위이력집합으로서 Instance별 생성(시작일),소멸(종료일)에 대한 기간을 관리하는 선분방식의 이력개념이 적용된다.
가입서비스 테이블은 모든 가입계약이 맺은 서비스계약에 대한 정보를 관리하는 행위이력집합으로서 이력정보는 시작일,종료일로 기간(선분) 개념이 적용된다.
청구계정 테이블은 한번이라도 청구계약을 맺은 고객에 대한 청구계정 개체집합으로서 청구계정ID는 개체로서 구성된다.
청구내역 테이블은 청구계정별 가입계약자가 사용한 서비스등에 대한 월별 청구내역을 관리하는 행위이력집합으로서 청구시점(청구년월)을 기준으로 데이터가 발생하므로 점방식의 이력개념이 적용된다.
청구상세내역 테이블은 청구계정별 가입계약자가 사용한 서비스등에 대한 청구항목별로 월별 청구내역을 관리하는 행위이력집합으로서 청구시점(청구년월)을 기준으로 데이터가 발생하므로 점방식의 이력개념이 적용된다. 그리고 회사의 수납 프로세스는 부분납을 허용하여 청구상세내역 테이블은 고객별 미납금액에 대한 정보를 관리하며 해당 항목은 청구금액 컬럼이다. 즉, 값이 0이면 완납을 의미하며 그 외에는 미납을 의미한다. 청구금액은 할인청구항목에 대해서는 (-)값도 존재할 수 있다.
수납 테이블은 청구계정별 수납정보를 관리하는 행위이력집합으로서 시점을 기준으로 데이터가 발생하므로 점방식의 이력개념이 적용된다. 그리고 해당 시점 정보를 관리하는 컬럼은 수납일자,수납이체일자,수납처리일자가 존재한다.
그럼 테이블별 어떤 컬럼으로 파티션 키를 선정하는 것이 최적인지 검토해 보자.
일반적으로 개체집합은 파티션으로 구성하지 않지만 DW 또는 CRM에서는 데이터 유형별 분석을 위해서 파티션으로 구성할 수 있다. 개체집합은 여러 가지 서브타입을 가질 수 있으며 이 중 주로 액세스되는 속성으로 파티션 키를 선정한다.
고객 테이블은 개인,법인,일반사업자,공공기관과 같은 고객유형이라는 서브타입이 존재할 수도 있으며 청각장애할인,시각장애할인과 같은 고객할인유형이라는 서브타입이 존재 할 수 있다. 일반적으로 DW 또는 CRM에서 주로 고객을 분석할 때 주요 관점이 고객유형이므로 이를 파티션 키로 선정할 수 있다.
가입계약 테이블은 가입계약행위에 대한 개체집합이지만 고객 테이블과는 달리 변경사항이 자주 발생하며 billing에서는 주로 기간별 고객상태정보가 필요하므로 굳이 해당 테이블을 파티션으로 구성할 필요는 없다고 판단된다.
청구계정 테이블도 굳이 해당 테이블을 파티션으로 구성할 필요는 없다고 판단된다.
일반적으로 대부분의 행위집합은 이력관점으로 구성되며 이력을 관리하는 방식은 이벤트 발생 시점을 관리하는냐(점개념) 아니면 기간으로 관리하느냐(선분개념)로 나뉠 수 있다. 이력관리 방식 및 업무적인 관점에 따라서 파티션 키를 선정하는 기준도 상이하다.
가입계약상태 테이블은 시작일,종료일로 기간별 이력을 관리하는 행위집합이다.
그러므로 해당 테이블의 파티션 키는 시작일 또는 종료일로 선정할 수 있다. 그럼 어떤 관점으로 어떤 컬럼을 파티션 키로 선정해야 하는가? 해당 테이블은 주로 billing에서 기본료 계산을 위해서 참조하며 해당 조건은 요금계산대상 시작일과 종료일로서 대부분 청구년월 직전 1개월이다. 예를 들어 5월 청구작업을 할 때 필요한 것은 고객이 10년 전에 가입했던지 1주일전에 가입했던지 4월1일1부터 4월30일까지 개통,정지,해지등의 이벤트가 존재하는 고객들의 정보이다. 즉, 현 시점의 정보가 주요 관점이므로 종료일자를 파티션 키로 선정하는 것이 타당하다. 또한 데이터 관리 관점에서도 언제 시작했느냐 보다는 언제 종료했느냐가 주요 관심사이다. Partition Range Interval은 트랜잭션량에 따라 년 또는 월단위로 하면된다.
가입서비스 테이블도 가입계약과 동일한 관점에서 볼 수 있으므로 종료일을 파티션 키로 선정한다.
그럼 선분개념으로 이력을 관리하는 경우에는 무조건 종료일자를 파티션 키로 선정하면 되는가? 예를 들어 고객 통화 데이터를 관리하는 통화호단위요금계산자료 테이블을 생각해 보자. 통화호단위요금계산자료란 CDR이라고도 통용된다. 해당 테이블은 개별 통화호에 대한 통화시작시각,통화종료시각을 관리한다. 통화호는 요금계산을 위한 기초자료이며 요금계산시 통화호에 대한 추출 관점은 요금계산 대상기간에 발생한 통화호이지 종료한 통화호는 아니다. 즉, 4월30일 오후11시58분에 발생해서 5월1일 오전 0시 5분에 종료된 통화호는 5월 청구대상이며 3월31일 오후11시58분에 발생해서 4월1일 오전 0시 5분에 종료된 통화호는 5월 청구대상이 아니라 4월 청구대상이라는 것이다. 즉 이런 경우에는 통화시작시각이 파티션 키로 선정되어야 한다. 여기서 좀더 생각할 것은 없는가? 대부분의 통화호는 통화 발생 즉시 과금시스템으로 전송되어 처리되지만 여러 가지 물리적인 요소에 의해서 통화호의 전송이 지연되는 경우가 가끔씩 발생한다. 어떤 경우에는 1개월이상이 지연되는 경우도 있다.
자 그러면 무엇을 고려해야 하는가? 결론은 통화시작시각,통화종료시각이 요금계산 대상 통화호에 대한 추출 기준이 될 수 없다는 것이다. 그래서 통화호 과금처리시각이라는 컬럼이 필요하며 이것이 해당 테이블의 파티션 키가 되어야 하는 것이다.
사례와 같이 파티션 키의 선정은 직관적이라기보다는 훨씬 더 전략적이라는 것이다.
지금까지 선분개념을 적용한 이력 집합에 대한 사례를 들었으며 이제 점개념을 적용한 이력집합에 대한 사례를 들어보자.
청구내역 테이블은 고객이 일정기간(보통 월초~월말) 사용한 통화료 및 기본료에 대한 월별 청구내역을 관리한다. 청구년월이라는 시점을 기준으로 청구 데이터는 처리되며 또한 데이터 백업의 기준이기도 하다. 즉, 청구 테이블은 청구년월을 파티션 키로 선정한다.
청구상세내역 테이블은 앞에서 설명했듯이 청구항목별 청구금액 및 미납금액을 관리한다. 즉, 해당 테이블은 청구업무뿐만 아니라 미납업무의 관점에서도 검토해야 한다. 일반적으로 대부분의 billing system에서 가장 골칫거리 중의 하나가 미납처리이며 미납해지고객에 대해서 불납결손처리하지 않으면 창사이래 회사의 모든 미납 데이터가 업무처리의 대상이다. 그러므로 해당 테이블의 파티션 키를 청구년월로만 산정하면 미납 데이터 추출시에는 테이블 전체를 처리하는 최악의 경우가 발생한다. 그럼 어떻게 해야 할 것인가?
청구금액 컬럼의 값이 0이 아닌 경우가 미납이므로 청구금액이 (+)이거나 (-)인 경우로 나눠서 추출하면 가능하므로 청구금액을 파티션 키에 포함하면 된다. 즉, 청구금액+청구년월이 파티션 키가 되는 것이다. 이렇게 하면 큰 문제는 없지만 매월 3개의 파티션이 생성되어야 하며 항상 OR 조건으로 처리해야 한다. 가능하다면 파티션 개수도 줄이고 OR 조건에 의한 처리를 피하기 위하여 의미적으로 해당 Instance는 미납이라는 것을 나타내기 위하여 미납여부 컬럼을 추가하여 이를 파티션 키로 선정할 수도 있다. 여기서 중요한 것은 결합파티션 키의 컬럼들간의 순서이다. 청구금액이든 미납여부이든 반드시 미납여부를 판단하기 위한 컬럼이 선두에 존재해야 한다. 만일 그렇지 않으면 해당 테이블의 파티션 키는 무용지물이 되는 것이다.
수납 테이블의 집합 개념은 앞에서 설명했듯이 점방식의 이력개념이 적용된다. 그리고 해당 시점 정보는 수납일자,수납이체일자,수납처리일자가 존재한다. 먼저 각 컬럼의 정확한 의미를 파악해 보자. 수납일자는 실제로 고객의 수납행위가 발생한 시점이며 수납이체일자는 금융기관에서 회사로 고객의 수납금액에 대한 이체가 발생한 시점이며 수납처리일자는 고객의 수납금액에 대해 전산상의 처리가 완료된 시점이다. 수납 테이블을 정보를 참조하는 경우는 결산,회계업무이며 대상은 실제 수납처리가 완료된 데이터들이다. 그럼 어떤 컬럼으로 파티션 키를 선정해야 하는가? 결론은 통화호단위요금계산자료 테이블의 파티션 키를 선정한 경우와 거의 유사하다. 수납일자 또는 수납이체일자는 수납행위집합에서 관리하고자 하는 정보일 뿐 실제 수납 데이터가 처리된 일자는 아니다. 즉, 천재지변등 여러 사유로 실제 처리작업이 지연될 수도 있는 것이다. 그러므로 수납처리일자를 파티션 키로 선정하는 것이 타당하다. 지금까지 여러 유형별 파티션 키를 선정하는 사례를 검토해 보았다.
그 외에 고려 되어야 할 부분은 각 파티션의 I/O 분산과 각 파티션의 크기를 어떻게 조절할 것인가에 대한 것으로 파티션의 장점을 최대한 활용하기 위해서는 반드시 적용이 되어야 하는 부분이다. 사실 파티션의 크기는 위에서 언급한 두 가지 조건만 만족하면 대부분이 비슷한 크기를 가지게 된다. 문제는 "I/O 분산을 어떻게 할 것인가?"에 달려 있다. 이 부분은 단순히 데이터를 테이블스페이스 단위로 나누는 것이 아니라 I/O 분산을 위해 물리적으로 다른 I/O channel를 가지고 있는 테이블스페이스에 분산시켜야 진정한 I/O 분산이 이루어 지게 된다. 본 사항은 뒤이은 연재에서 계속적으로 설명될 것이다.
이상으로 Partition Key 선정에 대해 살펴보았으며 다음 연재에서는 Partitioned Index의 제반사항에 대해 설명될 것이다.
|