데이터 정의
데이터 정의 (Data Definition)
관계형 데이터베이스에서는 원시 데이터가 **테이블(table)**에 저장돼요. 그런데 테이블을 만드는 것만으로는 부족해요. 데이터가 어떻게 생겼고 어떤 규칙을 따라야 하는지, 테이블끼리 어떤 관계를 갖는지까지 데이터베이스에 정의해 줘야 진짜 데이터를 안전하게 담을 수 있죠. 이 페이지에서는 테이블을 만들고 수정하고, 스키마로 조직하고, 권한을 부여하며, 상속·파티셔닝 같은 고급 기능까지 PostgreSQL의 데이터 정의(DDL, Data Definition Language) 세계를 개괄적으로 안내할게요.
이 장이 다루는 범위 (Overview)
이 장은 데이터를 담을 데이터베이스 구조를 만드는 방법을 다뤄요. 대부분의 내용은 테이블을 어떻게 생성·수정하고, 어떤 기능으로 테이블에 저장되는 데이터를 제어하는지에 집중돼 있어요. 이후에는 테이블을 어떻게 스키마(schema)로 정리하고, 권한(privilege)을 어떻게 부여하는지 살펴보죠. 마지막으로 상속(inheritance), 테이블 파티셔닝(table partitioning), 뷰(view), 함수(function), 트리거(trigger)처럼 데이터 저장에 영향을 주는 다른 기능들도 간단히 둘러볼게요.
주요 섹션 구성 (Table of Contents)
- 5.1. 테이블 기초 (Table Basics) — 테이블의 기본 개념과
CREATE TABLE. → ddl-basics - 5.2. 기본값 (Default Values) — 컬럼의 기본값 설정. → ddl-default
- 5.3. Identity 컬럼 (Identity Columns) —
GENERATED ... AS IDENTITY. → ddl-identity-columns - 5.4. 생성 컬럼 (Generated Columns) — 다른 컬럼에서 계산되는 컬럼. → ddl-generated-columns
- 5.5. 제약 조건 (Constraints) — CHECK, NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, EXCLUDE. → ddl-constraints
- 5.5.1. CHECK 제약 조건 — 컬럼 값이 만족해야 하는 조건식.
- 5.5.2. NOT NULL 제약 조건 — NULL 금지.
- 5.5.3. UNIQUE 제약 조건 — 중복 값 금지.
- 5.5.4. 기본 키 (Primary Keys) — 행을 식별하는 키.
- 5.5.5. 외래 키 (Foreign Keys) — 다른 테이블과의 참조 무결성.
- 5.5.6. 배타 제약 조건 (Exclusion Constraints) — 특정 조건을 동시에 만족하지 못하게.
- 5.6. 시스템 컬럼 (System Columns) — 모든 테이블에 암묵적으로 존재하는 컬럼들. → ddl-system-columns
- 5.7. 테이블 수정 (Modifying Tables) — 컬럼 추가/삭제, 제약 추가/삭제, 타입 변경, 이름 변경 등. → ddl-alter
- 5.8. 권한 (Privileges) — 객체 단위 접근 권한(
GRANT,REVOKE). → ddl-priv - 5.9. 행 보안 정책 (Row Security Policies) — 행 단위 접근 제어(
CREATE POLICY). → ddl-rowsecurity - 5.10. 스키마 (Schemas) — 스키마 생성, public 스키마, 검색 경로, 권한, 사용 패턴. → ddl-schemas
- 5.11. 상속 (Inheritance) — 테이블 간 상속 관계. → ddl-inherit
- 5.12. 테이블 파티셔닝 (Table Partitioning) — 선언적 파티셔닝, 상속 기반 파티셔닝, 파티션 프루닝, 모범 사례. → ddl-partitioning
- 5.13. 외부 데이터 (Foreign Data) — 외부 테이블과 데이터 래퍼. → ddl-foreign-data
- 5.14. 기타 데이터베이스 객체 (Other Database Objects) — 뷰, 함수, 트리거 등. → ddl-others
- 5.15. 의존성 추적 (Dependency Tracking) — 객체 간 의존 관계와 삭제 시 동작. → ddl-depend
테이블과 제약 조건 (Tables and Constraints)
테이블을 만들 때 가장 많이 챙기는 건 제약 조건(constraint) 이에요. 제약 조건은 데이터베이스가 스스로 데이터의 무결성을 지키게 만드는 장치죠.
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text NOT NULL,
price numeric CHECK (price > 0)
);
NOT NULL은 그 컬럼에 NULL이 들어오는 걸 막아요.UNIQUE는 같은 컬럼에 중복 값이 생기는 걸 막죠.PRIMARY KEY는 행을 식별하는 유일한 키예요. 내부적으로 UNIQUE + NOT NULL의 성격을 가져요.FOREIGN KEY는 이 테이블의 값이 다른 테이블의 값과 일치해야 한다는 참조 무결성을 보장합니다.CHECK는 컬럼 값이 특정 조건식을 만족해야 함을 강제해요.
테이블 수정 (Modifying Tables)
이미 만든 테이블은 ALTER TABLE로 수정해요.
-- 컬럼 추가
ALTER TABLE products ADD COLUMN description text;
-- 컬럼 제거
ALTER TABLE products DROP COLUMN description;
-- 제약 조건 추가
ALTER TABLE products ADD CONSTRAINT positive_price CHECK (price > 0);
-- 컬럼 이름 변경
ALTER TABLE products RENAME COLUMN name TO product_name;
컬럼 추가, 제거, 제약 추가·제거, 데이터 타입 변경, 이름 변경 등을 모두 ALTER TABLE로 처리해요. 자세한 규칙(예: 제약 제거 시 CASCADE 옵션)은 ddl-alter에서 다룹니다.
스키마 (Schemas)
스키마는 테이블·뷰·함수 같은 객체를 담는 이름 공간(namespace)이에요. 같은 이름의 객체도 각기 다른 스키마에 두면 충돌하지 않죠.
CREATE SCHEMA myschema;
CREATE TABLE myschema.products ( ... );
객체 이름을 스키마 없이 쓰면 PostgreSQL은 검색 경로(search path) 에 따라 스키마를 찾아요. 기본값으로는 public 스키마가 첫 검색 대상이 됩니다. 스키마를 쓰면 테이블을 논리적으로 그룹화하고, 여러 사용자가 같은 이름의 객체를 충돌 없이 만들 수 있어요.
권한 (Privileges)
테이블을 만들고 나면 기본적으로 만든 사람(소유자)만 접근할 수 있어요. 다른 역할(role)에게 접근을 허용하려면 GRANT를 써요.
GRANT SELECT, INSERT ON products TO app_user;
REVOKE DELETE ON products FROM app_user;
권한은 객체 단위로 관리되고, SELECT, INSERT, UPDATE, DELETE 등 다양한 종류가 있어요. ddl-priv에서 자세히 다룹니다.
상속과 파티셔닝 (Inheritance and Partitioning)
- 상속(Inheritance): 서브테이블이 부모 테이블의 컬럼을 물려받는 구조예요. 예전부터 있었던 PostgreSQL 고유 기능이지만 몇 가지 주의점이 있어요.
- 테이블 파티셔닝(Partitioning): 큰 테이블을 논리적으로 하나의 테이블이지만 물리적으로 여러 파티션으로 나누는 기법이에요. 쿼리가 필요 없는 파티션을 통째로 건너뛰는 파티션 프루닝(partition pruning) 덕분에 거대한 테이블에서도 성능을 유지할 수 있죠. 선언적 파티셔닝(declarative partitioning)이 권장돼요.