Django PostgreSQL 대용량 데이터 분할 저장

2023. 12. 30. 13:06개발/Django

728x90
반응형

데이터베이스 파티셔닝이란?

데이터베이스 파티셔닝(Database Partitioning)은 하나의 큰 테이블을 동일한 노드 내에서 여러 개의 작은 테이블로 나누는 기법입니다. 이는 흔히 샤딩(Sharding)과 혼동되기도 하지만, 샤딩은 데이터를 서로 다른 여러 노드에 분산시키는 반면, PostgreSQL의 파티셔닝은 단일 노드 내에서 테이블을 분할하는 방식을 사용합니다.

파티셔닝을 통해 쿼리 플래너가 보다 효율적으로 하위 집합을 탐색할 수 있도록 데이터를 구성할 수 있으며, 이는 데이터 조회, 삭제 및 삽입 속도를 크게 향상시키는 데 도움이 됩니다.

데이터 접근 패턴을 기준으로 파티셔닝 전략을 선택하는 것이 중요합니다. 예를 들어 생성 날짜를 기준으로 데이터를 자주 조회하는 경우, 날짜를 기반으로 파티션을 나누는 것이 효과적입니다. 지역이나 국가를 기준으로 데이터를 자주 사용하는 경우는 위치를 기반으로 파티셔닝하는 것이 좋습니다.

PostgreSQL에서 지원하는 파티셔닝 유형

1. 리스트 파티셔닝 (List Partitioning)

리스트 파티셔닝은 각 파티션에 특정 값을 명시적으로 지정할 수 있도록 합니다. 예를 들어 북미 기후 데이터를 미국, 캐나다, 멕시코 등 국가별로 나누고, 각 국가를 주(state)별로 더 세부적으로 파티셔닝할 수 있습니다.

2. 범위 파티셔닝 (Range Partitioning)

범위 파티셔닝은 가장 자주 사용되며 유용한 방법입니다. 숫자나 날짜 범위를 기준으로 테이블을 분할할 수 있습니다. 시간별 측정치를 저장하는 테이블을 날짜와 시간을 기준으로 파티셔닝하면 새로운 데이터를 조회하거나 오래된 데이터를 삭제하는 작업이 더욱 빨라집니다.

3. 해시 파티셔닝 (Hash Partitioning)

해시 파티셔닝은 데이터를 균등하게 분산시키기 위해 해시 값을 기반으로 모듈러와 나머지를 사용하여 데이터를 나눕니다. 데이터 구성의 명확한 기준이 없거나 데이터를 의사 무작위로 나누어야 할 경우에 적합합니다.

PostgreSQL 파티셔닝 작동 원리

파티셔닝된 테이블에서 중요한 점은 파티션 자체가 별도의 개별 테이블이라는 것입니다. 이들은 개별적으로 생성 및 조회할 수 있지만, 일반적으로 직접 조회하는 일은 드물며 상위 파티션 테이블을 통해 접근합니다.

또한, 파티션된 테이블(상위 테이블)은 데이터를 저장하지 않으며, 파티션 구조를 관리하는 스키마의 역할을 합니다.

PostgreSQL 파티션 테이블 생성 예시

먼저 일반 테이블을 생성해 비교해 봅니다.

CREATE TABLE people (
  id BIGSERIAL PRIMARY KEY,
  full_name text NOT NULL,
  birth_date date NOT NULL
);

파티션된 테이블을 생성하면 다음과 같습니다.

CREATE TABLE people_partitioned (
  id BIGSERIAL,
  full_name text NOT NULL,
  birth_date date NOT NULL,
  PRIMARY KEY (id, birth_date)
) PARTITION BY RANGE (birth_date);

여기서는 출생 날짜를 기준으로 범위 파티셔닝을 사용했으며, 기본 키는 파티션 기준 컬럼(birth_date)을 포함해야 합니다.

파티션 테이블을 실제로 생성하면:

CREATE TABLE people_partitioned_birthdays_1800_to_1850 PARTITION OF people_partitioned
    FOR VALUES FROM ('1800-01-01') TO ('1850-12-31');

CREATE TABLE people_partitioned_birthdays_1850_to_1900 PARTITION OF people_partitioned
    FOR VALUES FROM ('1850-12-31') TO ('1900-12-31');

CREATE TABLE people_partitioned_birthdays_1900_to_1950 PARTITION OF people_partitioned
    FOR VALUES FROM ('1900-12-31') TO ('1950-12-31');

CREATE TABLE people_partitioned_birthdays_1950_to_2000 PARTITION OF people_partitioned
    FOR VALUES FROM ('1950-12-31') TO ('2000-12-31');

CREATE TABLE people_partitioned_birthdays_2000_to_2050 PARTITION OF people_partitioned
    FOR VALUES FROM ('2000-12-31') TO ('2050-12-31');

각 파티션은 상위 테이블과 연결되며, 데이터를 삽입하거나 조회할 때는 항상 상위 파티션 테이블을 사용합니다.

INSERT INTO people_partitioned (full_name, birth_date) VALUES ('Bob Sponge', '2000-08-21');

SELECT * FROM people_partitioned;

파티셔닝의 주의사항 및 권장사항

  • 파티셔닝은 일반적으로 테이블이 100만 개 이상의 레코드를 가질 때 성능 이점을 제공합니다.
  • 수백 기가바이트 이하의 데이터에서는 관리 복잡성 대비 효과가 미미할 수 있으므로 신중히 고려해야 합니다.
  • 파티셔닝은 많은 이점이 있지만 더 많은 테이블을 생성하게 되고, 데이터 구조가 변경될 경우 관리가 어려워질 수 있습니다. 따라서 작은 데이터베이스에서는 파티셔닝이 필요하지 않을 수 있습니다.

결론

대규모 데이터를 효율적으로 관리하고 성능을 최적화하려면 Django와 PostgreSQL의 파티셔닝 전략을 이해하고 활용하는 것이 중요합니다. 데이터의 성격과 접근 패턴에 따라 적절한 파티셔닝 방식을 선택하면 효과적인 데이터 관리가 가능합니다.

 

출처 : https://pganalyze.com/blog/postgresql-partitioning-django