하이퍼테이블 만들고 구성하기

하이퍼테이블 만들고 구성하기

하이퍼테이블은 일반 PostgreSQL 테이블을 청크로 나눈 시간 파티셔닝 테이블이라서 아주 큰 데이터셋까지 확장할 수 있어요. 만드는 방법은 간단한데, 표준 CREATE TABLE 문에 WITH (timescaledb.hypertable)만 붙여 주면 돼요. 여기서는 새로 만드는 방법과 기존 테이블을 하이퍼테이블로 바꾸는 방법, 그리고 청크 간격·기본 인덱스 같은 구성 옵션을 하나씩 살펴볼게요.

출처: 공식문서 - Create and configure a hypertable

하이퍼테이블 새로 만들기

가장 단순한 형태는 첫 번째 timestamptz 컬럼을 파티션 컬럼으로 자동 감지하고, 필요하면 NOT NULL도 자동으로 추가해요.

CREATE TABLE sensor_data (
  time        TIMESTAMPTZ NOT NULL,
  device_id   INT,
  temperature DOUBLE PRECISION
) WITH (timescaledb.hypertable);

테이블에 타임스탬프 컬럼이 여러 개이거나 이름이 표준과 다르다면 파티션 컬럼을 명시적으로 지정해요.

CREATE TABLE order_events (
  created_at  TIMESTAMPTZ NOT NULL,
  order_id    BIGINT,
  status      TEXT
) WITH (
  timescaledb.hypertable,
  timescaledb.partition_column = 'created_at'
);

구성 옵션

WITH 절에서 아래 옵션을 지정해서 하이퍼테이블 생성 방식을 조절할 수 있어요.

옵션 기본값 설명
timescaledb.hypertable 필수. 이 테이블을 하이퍼테이블로 표시해요.
timescaledb.partition_column 자동 감지 데이터를 청크로 나눌 컬럼. 첫 timestamptz 컬럼에서 자동 감지하고, timestamptz 컬럼이 없거나 두 개 이상이면 반드시 명시해야 해요.
timescaledb.chunk_interval 7 days 각 청크가 담당하는 시간 범위. 수집 속도와 메모리에 맞춰 튜닝해요.
timescaledb.create_default_indexes true 파티션 컬럼에 인덱스를 자동 생성해요. 대량 적재 후 인덱스를 추가하려면 false로 설정해요.

청크 간격 설정

현재 활성 중인 청크들이 메모리에 들어갈 수 있도록 청크 간격을 고르는 게 좋아요. 기본은 7일이라 많은 워크로드에서 잘 동작하는데, 고처리량 수집에는 1일처럼 더 짧은 간격이 나을 수 있어요.

CREATE TABLE high_throughput_metrics (
  time        TIMESTAMPTZ NOT NULL,
  device_id   INT,
  value       DOUBLE PRECISION
) WITH (
  timescaledb.hypertable,
  timescaledb.chunk_interval = '1 day'
);

기본 인덱스 끄기

새 하이퍼테이블에 대량으로 데이터를 한꺼번에 넣을 땐 자동 인덱스 생성을 건너뛰고, 데이터를 다 넣은 뒤 인덱스를 추가하는 편이 빨라요.

CREATE TABLE bulk_load_target (
  time        TIMESTAMPTZ NOT NULL,
  device_id   INT,
  value       DOUBLE PRECISION
) WITH (
  timescaledb.hypertable,
  timescaledb.create_default_indexes = false
);

-- 데이터를 먼저 넣고, 그다음 인덱스 생성
CREATE INDEX ON bulk_load_target (time DESC);
CREATE INDEX ON bulk_load_target (device_id, time DESC);

기존 테이블 하이퍼테이블로 변환

이미 데이터가 있는 PostgreSQL 테이블은 create_hypertable() 함수에 migrate_data 옵션을 주면 하이퍼테이블로 바꿀 수 있어요.

SELECT create_hypertable('existing_table', by_range('time'), migrate_data => true);

아주 큰 테이블이라면 이 방식은 느리고 락이 많이 걸릴 수 있어요. 더 안전한 방법은 빈 하이퍼테이블을 만든 뒤 데이터를 배치로 옮기는 거예요.

CREATE TABLE new_table (LIKE existing_table INCLUDING ALL)
  WITH (timescaledb.hypertable);

INSERT INTO new_table SELECT * FROM existing_table;

더 알아보기 (Learn more)