본문 바로가기
Coding

PostgreSQL Partitioning 적용하는 방법

by Hide­ 2019. 8. 7.
반응형

PostgreSQL Version 10미만

1. 테이블 생성

먼저 아래와 같이 부모 테이블을 생성한다.

CREATE TABLE users(
    id bigint,
    nickname varchar(20),
    gender char(1),
)

다음으로 부모 테이블을 상속받아서 자식 테이블을 생성한다. 본 예제에서는 gender를 따라 남성/여성을 구분할 것이므로 users_maleusers_female 두개의 테이블을 만들었다.

CREATE TABLE users_male(
    CHECK (gender = 'M')
) INHERITS(users)
CREATE TABLE users_female(
    CHECK (gender = 'F')
) INHERITS(users)

여기서 CHECK 문법을 사용하여 위처럼 특정한 조건을 걸어줘야한다. 또한 INHERITS(부모테이블)을 사용하여 부모 테이블을 상속받아야 한다. 다음으로 실제 데이터가 users로 삽입될 때 gender에 따라 분기하여 파티셔닝된 테이블로 나누어서 들어가야하기 때문에 트리거 함수를 만들고 적용시켜줘야 한다.

2. 트리거 함수 생성

CREATE OR REPLACE FUNCTION users_insert() RETURNS TRIGGER AS $users$
    BEGIN
        IF (new.gender = 'F') THEN
            insert into users_female values (new.*);
        ELSIF (new.gender = 'M') THEN
            INSERT INTO users_male values (new.*);
        END IF;
        RETURN NULL;
    END;
$users$ LANGUAGE plpgsql;

만약 gender의 값이 F로 들어온다면 users_female 테이블로 삽입시키고 M이라면 users_male 테이블로 삽입시키는 간단한 예제이다.

3. 트리거 함수 적용

아래의 코드를 사용하여 위에서 생성한 트리거 함수를 적용시킨다.

CREATE TRIGGER tr_users_insert
  BEFORE INSERT ON users
  FOR EACH ROW EXECUTE PROCEDURE users_insert();

문법 자체도 간결하여 쉽게알 수 있겠지만 풀어서 설명하자면 users 테이블에 데이터를 삽입하기 전 users_insert() 함수를 실행시키는 것이라고 생각하면 된다.

4. 테스트

hide=# insert into users values(1, 'hide', 'M');
INSERT 0 0
hide=# insert into users values(2, 'test', 'M');
INSERT 0 0
hide=# insert into users values(3, 'john', 'F');
INSERT 0 0
hide=# select * from users_male;
 id | nickname | gender
----+----------+--------
  1 | hide     | M
  2 | test     | M
(2 rows)

hide=# select * from users_female;
 id | nickname | gender
----+----------+--------
  3 | john     | F
(1 row)

hide=# select * from users;
 id | nickname | gender
----+----------+--------
  1 | hide     | M
  2 | test     | M
  3 | john     | F
(3 rows)

위 내용은 PostgreSQL 버전 10까지의 내용이고 11부터는 정말 편리하게 파티셔닝을 추가할 수 있다.

PostgreSQL Version 10이상

1. 테이블 생성

먼저 아래와 같이 부모 테이블을 만든다.

CREATE TABLE users(
    id bigint,
    nickname varchar(20),
    gender char(1)
) PARTITION BY LIST(gender);

테이블을 생성할 때 PARTITION BY LIST(컬럼)을 통해 어떠한 컬럼을 대상으로 파티셔닝을 할지 명시해줘야 한다. (LIST이외에도 HASH, RANGE의 값을 줄 수 있다) 다음으로 자식 테이블 2개를 생성한다.

CREATE TABLE users_m PARTITION OF users FOR VALUES IN('M');
CREATE TABLE users_f PARTITION OF users FOR VALUES IN('F');

위에서는 CHECK를 통해 테이블을 생성했지만 이번에는 PARTITION OF 부모테이블 VALUES 조건 형태로 작성해주면 된다.

2. 테스트

hide=# insert into users values(1, 'hide', 'M');
INSERT 0 1
hide=# insert into users values(2, 'john', 'M');
INSERT 0 1
hide=# insert into users values(3, 'test', 'F');
INSERT 0 1
hide=# select * from users;
 id | nickname | gender
----+----------+--------
  3 | test     | F
  1 | hide     | M
  2 | john     | M
(3 rows)

hide=# select * from users_m;
 id | nickname | gender
----+----------+--------
  1 | hide     | M
  2 | john     | M
(2 rows)

hide=# select * from users_f;
 id | nickname | gender
----+----------+--------
  3 | test     | F
(1 row)