
PostgreSQL generated columns는 다른 컬럼 값으로 항상 계산되는 컬럼입니다. 일반 컬럼처럼 값을 직접 넣는 용도가 아니라, 같은 행의 값에서 파생되는 값을 스키마 안에 명확히 표현할 때 사용합니다.
PostgreSQL 18 공식 문서 기준으로 생성 컬럼에는 VIRTUAL과 STORED 두 종류가 있습니다. VIRTUAL은 읽을 때 계산되고 별도 저장 공간을 차지하지 않습니다. STORED는 행을 쓰거나 갱신할 때 계산되어 일반 컬럼처럼 디스크에 저장됩니다.
generated columns는 무엇을 해결하나
생성 컬럼은 같은 행 안의 원본 값에서 반복적으로 계산되는 값을 테이블 정의에 넣는 기능입니다. 예를 들어 센티미터 값을 기준으로 인치 값을 항상 계산해야 한다면, 애플리케이션마다 같은 계산식을 중복해서 두는 대신 테이블 컬럼 정의에 계산식을 둘 수 있습니다.
중요한 점은 생성 컬럼이 기본값과 다르다는 것입니다. 컬럼 기본값은 행이 삽입될 때 한 번 평가됩니다. 생성 컬럼은 원본 컬럼 값이 바뀌면 그에 따라 다시 계산되는 값이며, INSERT나 UPDATE에서 임의 값을 직접 지정할 수 없습니다. 필요한 경우 DEFAULT 키워드는 쓸 수 있지만, 생성된 값을 사용한다는 의미에 가깝습니다.

VIRTUAL과 STORED의 차이
VIRTUAL 생성 컬럼은 조회할 때 계산됩니다. PostgreSQL 18에서는 생성 컬럼을 만들 때 종류를 명시하지 않으면 기본적으로 VIRTUAL입니다. 저장 공간을 줄일 수 있지만, 조회 시점에 계산이 필요하다는 점을 고려해야 합니다.
STORED 생성 컬럼은 행이 쓰일 때 계산되고 결과가 저장됩니다. 자주 조회되거나 인덱스, 논리 복제 같은 주변 기능과 함께 볼 때는 STORED가 더 명확한 선택이 될 수 있습니다. 다만 저장 공간을 사용하고, 원본 값 변경 시 계산 결과도 함께 갱신됩니다.

| 구분 | VIRTUAL |
STORED |
|---|---|---|
| 계산 시점 | 읽을 때 계산 | 삽입 또는 갱신 시 계산 |
| 저장 공간 | 계산 결과를 별도로 저장하지 않음 | 계산 결과를 디스크에 저장 |
| PostgreSQL 18 기본값 | 기본 선택 | STORED를 명시해야 함 |
| 표현식 제한 | 내장 함수와 내장 타입 중심의 추가 제한이 있음 | 사용자 정의 타입이나 함수에 대한 제한이 상대적으로 적음 |
| 논리 복제 | 공식 문서 기준 생성 컬럼 복제 지원 대상이 아님 | publish_generated_columns 또는 컬럼 목록으로 게시 가능 |
기본 문법
생성 컬럼은 CREATE TABLE의 컬럼 정의에서 GENERATED ALWAYS AS 절로 만듭니다. PostgreSQL 18에서는 종류를 생략하면 VIRTUAL이므로, 저장 컬럼을 원한다면 STORED를 명시해야 합니다.
CREATE TABLE people (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm / 2.54)
);
저장 생성 컬럼을 명확히 쓰려면 다음처럼 작성합니다.
CREATE TABLE invoice_line (
quantity numeric NOT NULL,
unit_price numeric NOT NULL,
line_total numeric GENERATED ALWAYS AS (quantity * unit_price) STORED
);
표현식에서 지켜야 할 제한
생성 컬럼의 표현식은 아무 SQL이나 넣는 자리가 아닙니다. 공식 문서 기준으로 표현식은 immutable 함수만 사용할 수 있고, 서브쿼리를 사용할 수 없으며, 현재 행 이외의 대상을 참조할 수 없습니다.
- 다른 생성 컬럼을 참조할 수 없습니다.
- 시스템 컬럼은 일반적으로 참조할 수 없고, 예외적으로
tableoid만 허용됩니다. - 생성 컬럼에는 컬럼 기본값이나 identity 정의를 함께 둘 수 없습니다.
- 생성 컬럼은 파티션 키가 될 수 없습니다.
VIRTUAL생성 컬럼은 사용자 정의 타입을 가질 수 없고, 표현식도 사용자 정의 함수나 타입에 의존할 수 없습니다.
이 제한은 생성 컬럼을 데이터 정합성 규칙처럼 안정적으로 유지하기 위한 조건입니다. 현재 시간, 난수, 다른 테이블 조회처럼 실행 시점마다 값이 달라질 수 있는 계산은 생성 컬럼 표현식에 맞지 않습니다.
트리거와 권한에서 주의할 점
생성 컬럼은 개념적으로 BEFORE 트리거가 실행된 뒤 갱신됩니다. 따라서 BEFORE 트리거가 원본 컬럼 값을 바꾸면 생성 컬럼 결과에도 반영됩니다. 반대로 BEFORE 트리거 안에서 생성 컬럼 값을 읽는 것은 허용되지 않습니다.
권한도 별도로 봐야 합니다. PostgreSQL 문서는 생성 컬럼이 원본 컬럼과 별도 권한을 유지한다고 설명합니다. 특정 역할이 원본 민감 컬럼은 읽지 못하고 파생 컬럼만 읽게 하는 구성이 가능합니다. 다만 VIRTUAL 생성 컬럼의 보안성은 표현식에 사용된 함수가 leakproof인지에 영향을 받을 수 있고, 이 조건은 시스템이 강제로 검사하지 않습니다.
논리 복제에서는 STORED 기준으로 본다
PostgreSQL 18 문서 기준으로 생성 컬럼은 논리 복제에서 다룰 수 있지만, 현재 지원은 STORED 생성 컬럼에 한정됩니다. 게시자는 CREATE PUBLICATION의 publish_generated_columns 설정을 사용하거나, 컬럼 목록에 저장 생성 컬럼을 명시할 수 있습니다.
구독자 테이블에도 생성 컬럼이 있다면 게시자의 계산 결과가 그대로 쓰인다고 단순하게 생각하면 안 됩니다. 공식 문서는 게시자와 구독자 양쪽이 생성 컬럼을 가진 경우 구독자 쪽 생성 컬럼 값이 사용되는 예를 설명합니다. 특히 PostgreSQL이 아닌 시스템으로 데이터를 보내는 구조라면 저장 생성 컬럼을 일반 컬럼으로 복제해야 하는 요구가 생길 수 있습니다.

언제 VIRTUAL을 선택하나
VIRTUAL은 계산식이 단순하고, 저장 공간을 늘리고 싶지 않으며, 조회 시점 계산 비용이 부담되지 않을 때 적합합니다. PostgreSQL 18의 기본값이므로 새 스키마를 만들 때 별도 이유가 없다면 먼저 검토할 수 있습니다.
다만 표현식이 사용자 정의 함수나 타입에 의존한다면 VIRTUAL 제약에 걸릴 수 있습니다. 또한 자주 조회되는 파생 값이고 계산 비용이 의미 있게 크다면 STORED와 인덱스 설계를 함께 보는 편이 낫습니다.
언제 STORED를 선택하나
STORED는 계산 결과를 저장해야 할 이유가 있을 때 선택합니다. 조회마다 계산하지 않고 저장된 값을 읽고 싶거나, 사용자 정의 함수와 타입을 포함한 표현식이 필요하거나, 논리 복제에서 생성 컬럼 값을 게시해야 한다면 STORED가 더 분명합니다.
대신 저장 공간과 쓰기 시점 계산 비용을 받아들여야 합니다. 원본 컬럼이 자주 바뀌는 테이블에서는 갱신 시 계산 부담도 같이 생길 수 있습니다.
운영 기준
- 생성 컬럼은 애플리케이션 중복 계산을 줄이는 도구이지, 임의 값을 저장하는 컬럼이 아닙니다.
- PostgreSQL 18에서는 종류를 생략하면
VIRTUAL이므로, 기존STORED전제의 마이그레이션 스크립트는 명시 여부를 확인합니다. - 표현식은 immutable, 같은 행 기준, 서브쿼리 없음이라는 제한을 먼저 확인합니다.
- 사용자 정의 함수나 타입이 필요하면
VIRTUAL보다STORED를 우선 검토합니다. - 논리 복제로 생성 컬럼 값을 보내야 한다면
STORED와 publication 설정을 함께 봅니다. - 민감한 원본 컬럼을 숨기고 파생 값만 노출하려면 생성 컬럼 권한과 표현식 함수의 보안 특성을 함께 검토합니다.
자주 묻는 질문
generated columns와 DEFAULT는 같은 기능인가
아닙니다. DEFAULT는 값을 지정하지 않은 삽입 시점에 한 번 평가되는 기본값입니다. 생성 컬럼은 다른 컬럼 값에서 계산되고, 원본 값이 바뀌면 계산 결과도 바뀌는 파생 컬럼입니다.
PostgreSQL 18에서 STORED를 생략해도 되나
저장 생성 컬럼이 목적이라면 생략하면 안 됩니다. PostgreSQL 18에서는 생성 컬럼의 기본 종류가 VIRTUAL입니다. 저장 결과가 필요하면 STORED를 명시해야 합니다.
생성 컬럼을 파티션 키로 쓸 수 있나
공식 문서 기준으로 생성 컬럼은 파티션 키가 될 수 없습니다. 파티션 설계에 필요한 값이라면 원본 컬럼, 표현식 파티션, 별도 관리 컬럼 중 어떤 방식이 맞는지 따로 검토해야 합니다.
정리
PostgreSQL generated columns의 핵심 기준은 계산 시점입니다. VIRTUAL은 읽을 때 계산하고 저장 공간을 쓰지 않습니다. STORED는 쓸 때 계산해 결과를 저장합니다.
PostgreSQL 18에서는 VIRTUAL이 기본값이 되었기 때문에, 기존처럼 저장 생성 컬럼을 전제로 작성한 스키마라면 STORED 명시 여부를 확인해야 합니다. 표현식 제한, 조회 비용, 논리 복제 필요성, 권한 분리 요구를 함께 보면 선택 기준이 명확해집니다.
'프로그래밍 > 서버, DBMS' 카테고리의 다른 글
| PostgreSQL OAuth 인증 기준 (0) | 2026.08.15 |
|---|---|
| PostgreSQL sslcertmode 기준 정리 (0) | 2026.08.12 |
| PostgreSQL require_auth 기준 정리 (1) | 2026.08.08 |
| PostgreSQL load_balance_hosts 기준 정리 (0) | 2026.08.03 |
| PostgreSQL gssencmode 기준 정리 (0) | 2026.07.29 |





