`ALTER TABLE` — 테이블 정의 변경

ALTER TABLE — 테이블 정의 변경

테이블에 열을 추가하거나, 제약 조건을 바꾸거나, 이름을 바꾸거나, 파티션을 다루는 등 테이블의 구조를 수정하고 싶을 때, PostgreSQL에서 가장 흔하게 쓰는 명령이 바로 ALTER TABLE이에요. 테이블을 만들었다면 그 다음 단계는 거의 다 이 명령으로 시작해요.

출처: PostgreSQL 문서

본문

ALTER TABLE은 기존 테이블의 정의를 변경해요. 열 추가/삭제/이름 변경, 데이터 타입 변경, 제약 조건 추가/삭제, 기본값·null 허용 여부 변경, 파티셔닝, 테이블·열·제약 조건의 저장소 특성까지 정말 다양한 작업을 한 명령으로 처리할 수 있어요.

Synopsis (개요)

여러 변형(form)이 있으니 대표적인 것들을 살펴볼게요. (전체 목록은 PostgreSQL 문서를 참고하세요.)

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    action [, ... ]

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME [ COLUMN ] column_name TO new_column_name

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
    RENAME TO new_name

ALTER TABLE [ IF EXISTS ] name
    SET SCHEMA new_schema

ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
    SET TABLESPACE new_tablespace [ NOWAIT ]

where action is one of:

    ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ]
        [ column_constraint [ ... ] ]
    DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ]
    ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ]
        [ USING expression ]
    ALTER [ COLUMN ] column_name SET DEFAULT expression
    ALTER [ COLUMN ] column_name DROP DEFAULT
    ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL
    ALTER [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
    ALTER [ COLUMN ] column_name SET STATISTICS integer
    ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] )
    ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] )
    ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    ADD table_constraint [ NOT VALID ]
    DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ]
    ADD table_constraint_using_index
    ENABLE TRIGGER [ trigger_name | ALL | USER ]
    DISABLE TRIGGER [ trigger_name | ALL | USER ]
    ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT }
    DETACH PARTITION partition_name [ FINALIZE ]
    OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
    SET TABLESPACE new_tablespace
    SET ( storage_parameter [= value] [, ... ] )
    RESET ( storage_parameter [, ... ] )
    ...

action의 목록은 PostgreSQL 버전마다 더 늘어나요. 특히 파티셔닝 관련 동작(ATTACH/DETACH PARTITION, ALTER TABLE ... PARTITION OF 등)이 자주 추가돼요.

Description (설명)

ALTER TABLE의 각 변형은 아래와 같은 역할을 해요.

  • 열 추가/삭제ADD COLUMN은 새 열을 추가하고, DROP COLUMN은 열과 그 열에 의존하는 제약·인덱스를 제거해요. CASCADE를 쓰면 열에 의존하는 객체까지 함께 제거하고, RESTRICT는 의존 객체가 있으면 거부해요.
  • 열 데이터 타입 변경ALTER COLUMN ... TYPE은 열의 타입을 바꿔요. USING 절을 쓰면 기존 값을 새 타입으로 변환하는 방식을 직접 지정할 수 있어요. 타입 변경은 기존 테이블을 다시 쓰는 작업이라 대형 테이블에서는 비용이 클 수 있어요.
  • 기본값과 null 제약SET DEFAULT/DROP DEFAULT는 기본값을 설정하거나 제거하고, SET NOT NULL/DROP NOT NULL은 null 허용 여부를 바꿔요.
  • 제약 조건ADD table_constraint는 새 제약을 추가하고, DROP CONSTRAINT는 제약을 제거해요. NOT VALID와 함께 추가하면 기존 행에는 검증 없이 제약만 걸고, 나중에 VALIDATE CONSTRAINT로 검증할 수 있어요. 대형 테이블에서 검증 비용을 분산하고 싶을 때 유용해요.
  • 트리거ENABLE TRIGGER/DISABLE TRIGGER로 트리거를 일시적으로 켜거나 끌 수 있어요.
  • 파티셔닝ATTACH PARTITION/DETACH PARTITION으로 파티션을 붙이거나 떼고, ALTER TABLE ... PARTITION OF로 파티션 테이블의 부모 매핑을 바꿔요.
  • 저장 특성SET TABLESPACE는 테이블을 다른 테이블스페이스로 옮기고, SET (storage_parameter)로 autovacuum 임계값, fillfactor 같은 저장 파라미터를 조정해요.
  • 이름·소유자·스키마RENAME TO, OWNER TO, SET SCHEMA로 각각 이름, 소유자, 스키마를 변경해요.

IF EXISTS를 지정하면 대상이 없어도 오류 대신 알림만 내요. ONLY는 상속 계층에서 해당 테이블만(자식 제외) 대상으로 하고, 기본은 자식 테이블까지 포함해요.

Parameters (파라미터)

  • name — 변경할 기존 테이블의 이름(선택적으로 스키마로 한정).
  • column_name / new_column_name — 변경할 열과 새 열 이름.
  • data_type — 열에 설정할 새 데이터 타입.
  • constraint_name — 추가/제거할 제약 이름.
  • CASCADE / RESTRICT — 종속 객체를 자동으로 함께 변경/삭제할지(CASCADE), 아니면 존재하면 거부할지(RESTRICT).
  • new_name — 테이블의 새 이름.
  • new_schema — 테이블을 옮길 새 스키마.
  • new_owner — 새 소유자 역할.
  • storage_parameter — 설정하거나 초기화할 저장 파라미터.

Notes (주의)

ALTER TABLE을 쓰려면 보통 테이블의 소유자여야 해요. 일부 동작(예: SET TABLESPACE)은 추가 권한이 필요할 수 있어요.

데이터 타입 변경처럼 테이블을 다시 쓰는 동작은 대형 테이블에서 오래 걸리고 AccessExclusiveLock을 걸 수 있으므로, 운영 중인 서비스에서는 VACUUM FULL과 함께 영향 범위를 잘 확인하고 실행해야 해요.

ADD COLUMN은 일부 예외를 제외하고 PostgreSQL 11부터는 메타데이터만 갱신해서 빠르게 처리돼요. DEFAULT 값을 갖는 열을 추가하면 기존 행에 그 값이 채워져서 테이블을 다시 쓰게 될 수 있어요.

Examples (예시)

기존 테이블에 열을 하나 추가하는 예시예요.

ALTER TABLE distributors ADD COLUMN address varchar(30);

열의 데이터 타입을 바꾸는 예시예요.

ALTER TABLE distributors ALTER COLUMN address TYPE varchar(80);

테이블 이름을 바꾸는 예시예요.

ALTER TABLE distributors RENAME TO suppliers;

기본값이 있는 열을 추가해서 기존 행에도 그 값을 채우는 예시예요.

ALTER TABLE distributors ADD COLUMN isbn text DEFAULT '0';

Compatibility (호환성)

ALTER TABLE의 대부분의 형태는 SQL 표준의 일부분이에요. ADD COLUMN, DROP COLUMN, ALTER COLUMN TYPE, ADD CONSTRAINT 등은 표준에 있는 형태예요. 다만 IF EXISTS, SET STATISTICS, SET STORAGE, 파티션 관련 동작 등 많은 옵션은 PostgreSQL 확장이에요.

더 알아보기 (Learn more)

  • 테이블을 만드는 CREATE TABLE과 삭제하는 DROP TABLE을 함께 확인해요.
  • 파티셔닝과 인덱스 관리에 대한 자세한 내용은 PostgreSQL 문서의 테이블 파티셔닝 섹션에서 볼 수 있어요.