티스토리 뷰


분할 기법  


분할 기법(partitioning)은 하나의 테이블을 여러 독립적인 논리적 단위로 분할하는 기법이다. 분할 기법에서 사용하는 분할된 단위를 분할(partition)이라 한다. 분할은 주로 관리의 편의(manageability), 성능(performance), 가용성(availability)의 목적으로 사용한다. 분할을 적용함으로써 얻을 수 있는 효과는 다음과 같다.

    a. 대용량 테이블의 관리 향상
    b. 데이터 조회 시 접근 범위를 줄임으로써 성능 향상
    c. 디스크 I/O를 분산함으로써 성능 향상 및 물리적 부하 감소
    d. 여러 분할로 나눔으로써 전체 데이터의 훼손 가능성 감소 및 가용성 향상
    e. 스토리지 비용의 최적화

CUBRID는 영역 분할(Range Partitioning), 해시 분할(Hash Partitioning), 리스트 분할(List Partitioning)의 세 가지 분할을 제공한다.
한 테이블이 가질 수 있는 최대 분할 수는 1024이다. 테이블의 각 분할은 그 테이블의 서브 테이블로 생성된다. 분할 정의를 통해 생성된 서브 테이블은 사용자가 임의로 내용을 변경하거나 삭제할 수 없다. 서브 테이블의 이름은 class_name_p_partition_name”의 형식으로 시스템 테이블에 등록된다. 데이터베이스 사용자는 db_class 뷰와 db_partition 뷰에서 분할의 정보를 확인할 수 있다. 또 다른 확인 방법은 CUBRID 매니저나 CSQL 인터프리터의 ;sc <table_name> 명령을 사용하는 것이다.


레인지 분할 기법  

레인지 분할은 한 컬럼의 값의 범위를 기준으로 분할한다. 테이블을 생성할 때 분할은 정의하는 구문의 형식은 다음과 같다.

레인지 분할 정의
구문
CREATE TABLE(
     ...
     )
     PARTITION BY RANGE ( <partition expression> ) (
     PARTITION <partition name> VALUES LESS THAN ( <partition RANGE value> ),
     PARTITION <partition name> VALUES LESS THAN ( <partition RANGE value> ) ),
     ... )
     )


질문
신규 서비스에서 사용될 게시판에 등록될 글 수가 100만 건 정도로 예상이 되므로 등록 글의 아이디가 50만 미만이면 분할 명을 post_limit_500000로 지정하고, 50만 이상이면 분할 명을 post_limit_1000000로 지정하라.

SQL문
-- 테이블 생성 및 분할 정의 질의
CREATE TABLE "post_part"(
     "id" INTEGER NOT NULL UNIQUE,
     "subject" character varying(50) NOT NULL,
     "content" string NOT NULL,
     "click_count" INTEGER DEFAULT 0 NOT NULL 

PARTITION BY RANGE (id) 
(PARTITION post_limit_500000 VALUES LESS THAN (500000),
PARTITION post_limit_1000000 VALUES LESS THAN (1000000));
    
     -- 데이터 삽입 질의
INSERT INTO post_part VALUES (1, 'Partition Test 1', 'CONTENT 1', 0);
INSERT INTO post_part VALUES (2, 'Partition Test 2', 'CONTENT 2', 0);
INSERT INTO post_part VALUES (250001, 'Partition Test 3', 'CONTENT 3', 0);
INSERT INTO post_part VALUES (250002, 'Partition Test 4', 'CONTENT 4', 0);
INSERT INTO post_part VALUES (500001, 'Partition Test 5', 'CONTENT 5', 0);
INSERT INTO post_part VALUES (500002, 'Partition Test 6', 'CONTENT 6', 0);
INSERT INTO post_part VALUES (750001, 'Partition Test 7', 'CONTENT 7', 0);
INSERT INTO post_part VALUES (750002, 'Partition Test 8', 'CONTENT 8', 0);


결과 출력 SQL문
SELECT * FROM "post_part__p__post_limit_500000";
SELECT * FROM "post_part__p__post_limit_1000000";


결과 테이블
no
id
subject
content
click_count
1
1
Partition Test 1
CONTENT 1
0
2
2
Partition Test 2
CONTENT 2
0
3
250001
Partition Test 3
CONTENT 3
0
4
250002
Partition Test 4
CONTENT 4
0
[ post_limit_500000 결과]

no
id
subject
content
click_count
1
500001
Partition Test 5
CONTENT 5
0
2
500002
Partition Test 6
CONTENT 6
0
3
750001
Partition Test 7
CONTENT 7
0
4
750002
Partition Test 8
CONTENT 8
0
[post_limit_1000000 결과]

주의 사항
한 테이블이 가질 수 있는 최대 분할 개수는 1024개이다.

분할 키 값이 NULL이면, 첫 번째 분할에 저장된다.


레인지 분할 재정의
설명
ALTER 문의 REORGANIZE PARTITION 절을 이용하여 분할을 재정의한다. 재정의를 통해 복수개의 분할을 1개에 결합할 수 있으며, 1개의 분할을 복수 개로 분리할 수 있다.

구문
ALTER {TABLE | CLASS} <table name>
REORGANIZE PARTITION
<alter PARTITION NAME comma list>
INTO ( <partition definition comma list> )`
    
     재정의 내용을 정의. 복수개인 경우 쉼표(,)로 구분:
     PARTITION <partition name> VALUES LESS THAN ( <partition RANGE value> ),....


분할 재정의 SQL문
신규 서비스에 사용되는 게시판의 사용자 수가 급격히 증가하였기 때문에 기존의 post_limit를 재분할하는 예이다.

-- 50만 기준 분할, 25만/50만 기준으로 재 분할
ALTER TABLE post_part REORGANIZE PARTITION post_limit_500000 INTO (
     PARTITION post_limit_250000 VALUES LESS THAN (250000),
     PARTITION post_limit_500000 VALUES LESS THAN (500000)
);

-- 100만 기준 분할, 75만/100만 기준으로 재 분할
ALTER TABLE post_part REORGANIZE PARTITION post_limit_1000000 INTO (
     PARTITION post_limit_750000 VALUES LESS THAN (750000),
     PARTITION post_limit_1000000 VALUES LESS THAN (1000000)
);

-- 각각의 분할 별 조회 질의
SELECT * FROM "post_part__p__post_limit_250000";
SELECT * FROM "post_part__p__post_limit_500000";
SELECT * FROM "post_part__p__post_limit_750000";
SELECT * FROM "post_part__p__post_limit_1000000";


결과 테이블
no
id
subject
content
click_count
1
1
Partition Test 1
CONTENT 1
0
2
2
Partition Test 2
CONTENT 2
0
[ post_limit_250000 결과]

no
id
subject
content
click_count
1
250001
Partition Test 3
CONTENT 3
0
2
250002
Partition Test 4
CONTENT 4
0
[ post_limit_500000 결과]

no
id
subject
content
click_count
1
500001
Partition Test 5
CONTENT 5
0
2
500002
Partition Test 6
CONTENT 6
0
[ post_limit_750000 결과]

no
id
subject
content
click_count
1
750001
Partition Test 7
CONTENT 7
0
2
750002
Partition Test 8
CONTENT 8
0
[ post_limit_1000000 결과]


레인지 분할 추가 및 삭제
분할 추가 구문
ALTER { TABLE | CLASS } <table_name>
ADD PARTITION <partition definition comma list>
<alter PARTITION NAME comma list>
PARTITION <partition_name> VALUES LESS THAN ( <partition_range_value> ),...


분할 추가 예제
신규 서비스의 사용자가 꾸준히 증가함에 따라 게시판의 글 수도 계속 증가하고 있다. post_limit가 100만 이상일 때, 지정되는 테이블 분할을 추가하라.

ALTER TABLE post_part ADD PARTITION (PARTITION post_limit_max VALUES LESS THAN MAXVALUE); 
     
-- id가 100만 이상인 데이터 삽입 질의
INSERT INTO post_part VALUES (1000001, 'Partition Test 9', 'CONTENT 9', 0); 
     
-- limit_max 분할 조회
SELECT * FROM "post_part__p__post_limit_max";


결과 테이블
no
id
subject
content
click_count
1
1000001
Partition Test 9
CONTENT 9
0

분할 추가 시 주의 사항
    a. 영역 분할을 추가할 때는 분할 기준 값이 기존의 분할보다 큰 값만 추가할 수 있다. 따라서, 위의 예제처럼 MAXVALUE로 최대값을 설정하면 더 이상 분할을 추가할 수 없다(분할 재정의를 통해서 MAXVALUE를 다른 값으로 변경하면 분할 추가 가능).
    b. 기존의 분할보다 작은 분할 기준 값을 추가하려면 분할 재정의를 이용한다.

분할 삭제 구문
ALTER {TABLE | CLASS} <table_name>
DROP PARTITION <partition_name>


분할 삭제 예제
다음은 post_part 테이블의 post_limit_max 분할을 삭제한다.

ALTER TABLE post_part DROP PARTITION post_limit_max;


분할 삭제 시 주의 사항
    a. 분할된 테이블을 삭제하면 해당 분할 내에 저장된 데이터도 모두 삭제된다.
    b. 데이터는 유지한 채 테이블의 분할을 변경하는 경우 ALTER TABLE...REORGANIZE PARTITION 문을 사용한다
    c. 분할을 삭제할 경우 삭제된 행의 수를 반환하지 않는다. 테이블과 분할을 유지한 채로 데이터만 삭제하고 싶은 경우 DELETE 문을 수행한다.



해시 분할 기법  

해시 분할 기법은 한 컬럼의 값의 해시 값을 기준으로 분할한다. 테이블을 생성할 때 분할을 정의 하는 구문의 형식은 다음과 같다.

CREATE TABLE (
     ...
     )
     ( PATITION BY HASH ( <partition expression> )
     PATITIONS ( <partition count> )
     )


해시 분할 정의
문제 1
post_part 테이블을 재 생성하고 id 값을 기준으로 4개의 해시 분할을 정의하라. 해시 분할은 분할의 수만 지정하고 이름은 지정하지 않으므로 p0, p1… 과 같이 자동으로 이름이 부여된다.

SQL문
-- 기존의 post_part 테이블 삭제
DELETE FROM post_part;

-- 테이블 재생성 및 해시 분할 정의 질의
CREATE TABLE "post_part"(
     "id" INTEGER NOT NULL UNIQUE,
     "subject" character varying(50) NOT NULL,
     "content" string NOT NULL,
     "click_count" INTEGER DEFAULT 0 NOT NULL
)
PARTITION BY HASH (id) PARTITIONS 4;
    
     -- 데이터 삽입 질의
INSERT INTO post_part VALUES (1, 'Partition Test 1', 'CONTENT 1', 0);
INSERT INTO post_part VALUES (2, 'Partition Test 2', 'CONTENT 2', 0);
INSERT INTO post_part VALUES (250001, 'Partition Test 3', 'CONTENT 3', 0);
INSERT INTO post_part VALUES (250002, 'Partition Test 4', 'CONTENT 4', 0);
INSERT INTO post_part VALUES (500001, 'Partition Test 5', 'CONTENT 5', 0);
INSERT INTO post_part VALUES (500002, 'Partition Test 6', 'CONTENT 6', 0);
INSERT INTO post_part VALUES (750001, 'Partition Test 7', 'CONTENT 7', 0);
INSERT INTO post_part VALUES (750002, 'Partition Test 8', 'CONTENT 8', 0); 
     
-- 결과 테이블 p0, p1, p2, p3 조회
SELECT * FROM "post_part__p__p0"
SELECT * FROM "post_part__p__p1"
SELECT * FROM "post_part__p__p2"
SELECT * FROM "post_part__p__p3";


결과 테이블
no
id
subject
content
click_count
1
250001
Partition Test 3
CONTENT 3
0
2
250002
Partition Test 4
CONTENT 4
0
3
500001
Partition Test 5
CONTENT 5
0
4
750002
Partition Test 8
CONTENT 8
0
[p0 결과]

no
id
subject
content
click_count
1
1
Partition Test 1
CONTENT 1
0
2
2
Partition Test 2
CONTENT 2
0
3
500002
Partition Test 6
CONTENT 6
0
[p1 결과]

no
id
subject
content
click_count
[p2 결과]

no
id
subject
content
click_count
1
750001
Partition Test 7
CONTENT 7
0
[p3 결과]

설명
해시 분할 기법은 한 레코드가 삽입되면 어느 분할로 삽입될지 알 수 없으므로, 관리의 편의성보다는 저장 및 조회시의 성능에 초점을 맞춘 기법이다. 해시 분할은 내부의 해시 함수를 통해서 각 분할의 분포를 다소 균형 있게 유지할 수 있다.


해시 분할 재정의
설명
ALTER 문의 COALESCE PARTITION 절을 이용하여 재정의할 수 있다. 해시 분할이 재정의되는 경우 인스턴스는 그대로 보존된다.

구문
ALTER { TABLE | CLASS } <table_name>
COALESCE PARTITION <partition_count>


SQL문
다음 예제는 분할 개수를 4개수를 2개로 줄이는 SQL문이다.

ALTER TABLE post_part COALESCE PARTITION 2;


주의 사항
    a. 분할의 개수를 감소시키는 재편성 결합만 가능하다.
    b. 분할의 수를 늘리고자 하는 경우에는 영역 분할에서와 같은 ALTER TABLE ... ADD PARTITION 구문을 이용한다.
    c. 분할 재정의 후에 최소 1개 이상의 분할이 남아 있어야 한다.



리스트 분할 기법  

리스트 분할은 한 컬럼의 값 목록(list)를 기준으로 분할하는 방법이다. 테이블을 생성할 때 분할을 정의하는 구문의 형식은 다음과 같다.


CREATE TABLE(
     ...
     )
     PARTITION BY LIST ( <partition_expression> ) (
     PARTITION <partition_name_1> VALUES IN ( <partition_value_list_1> ),
     PARTITION <partition_name_2> VALUES IN ( <partition_value_list_2> ),
     ...
);


리스트 분할 정의
문제 1
다음은 선수의 이름과 종목 정보를 담고 있는 athlete2 테이블을 생성하고 종목에 따른 리스트 분할을 정의하는 예제이다.`

SQL문 1
CREATE TABLE athlete2( NAME VARCHAR(40), event VARCHAR(30) )
     PARTITION BY LIST (event) (
     PARTITION event1 VALUES IN ('Swimming', 'Athletics ' ),
     PARTITION event2 VALUES IN ('Judo', 'Taekwondo','Boxing'),
     PARTITION event3 VALUES IN ('Football', 'Basketball', 'Baseball')
);


결과 화면 1

문제 2
다음은 예제 1에서 생성한 리스트 분할에 데이터를 삽입하는 예제이다. 마지막 질의와 같이 데이터 삽입 시 분할 표현 식에서 기술하였던 리스트에 없는 값으로 삽입하는 경우에는 삽입이 이루어지지 않는다.

SQL문 2
INSERT INTO athlete2 VALUES ('Hwang Young-Cho', 'Athletics');
INSERT INTO athlete2 VALUES ('Lee Seung-Yuop', 'Baseball');
INSERT INTO athlete2 VALUES ('Moon Dae-Sung','Taekwondo');
INSERT INTO athlete2 VALUES ('Cho In-Chul', 'Judo');
INSERT INTO athlete2 VALUES ('Hong Kil-Dong', 'Volleyball');


결과 화면 2

설명
리스트 분할 기법을 사용할 경우 분할 값 목록에 나타나지 않은 값을 가진 레코드는 테이블에 삽입되지 않는다. 따라서 컬럼 값들의 종류가 지나치게 많거나, 사전에 알지 못하는 새로운 값이 삽입될 가능성이 있으면 리스트 분할 기법을 사용하지 않는 것이 바람직하다. 그리고 분할 표현식이 널 값인 레코드가 삽입되게 하려면 분할 값 목록에 반드시 NULL을 명시 해야 한다.


리스트 분할 재정의
설명
ALTER 문의 REORGANIZE PARTITION 절을 이용하여 재정의할 수 있다. 재정의를 통해 복수의 분할을 1개에 결합할 수 있으며, 1개의 분할을 복수 개로 분리할 수 있다.

구문
ALTER {TABLE | CLASS} <table_name>
REORGANIZE PARTITION
<alter PARTITION NAME comma list>
INTO ( <partition definition comma list> )
     PARTITION definition comma list:
     PARTITION <partition_name> VALUES IN ( <partition_value_list>),...


SQL문 1
다음은 종목에 따라 리스트 분할한 athlete2 테이블을 분할 event2를 event2_1(유도), event2_2(태권도, 복싱)로 재정의하는 예제이다.

ALTER TABLE athlete2 REORGANIZE PARTITION event2 INTO
(PARTITION event2_1 VALUES IN ('Judo'),
PARTITION event2_2 VALUES IN ( 'Taekwondo','Boxing'));


결과 화면 1

SQL문 2
다음은 예제 1에서 분할한 event2_1과 event2_2를 다시 event2 하나로 결합하는 예제이다.

ALTER TABLE athlete2 REORGANIZE PARTITION event2_1, event2_2 INTO
(PARTITION event2 VALUES IN('Judo','Taekwondo','Boxing'));


결과 화면 2


리스트 분할 삭제
설명
ALTER 구문의 DROP PARTITION 절을 이용하여 분할을 삭제할 수 있다.

구문
ALTER {TABLE | CLASS} <table_name>
DROP PARTITION <partition_name>


SQL문
다음은 종목에 따라 리스트 분할한 athlete2 테이블을 생성하고 event3 분할을 삭제하는 예제이다.

ALTER TABLE athlete2 DROP PARTITION event3;




출처 : http://cafe.naver.com/studycubrid.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=703

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크