- 일반적인 RDBMS의 기능에 더해 객체지향적 개념을 지원하는 객체-관계형 (ORDBMS) 데이터베이스
- 상속 (inheritance): 한 테이블이 다른 테이블의 구조 (칼럼)을 상속받아 확장할 수 있음
CREATE TABLE admins (...) INHERITS (users);
- 사용자가 직접 데이터 타입, 함수, 연산자, 인덱싱을 정의할 수 있음
- ANSI SQL 표준 준수 및 JOIN, CTE, Window Function, Sub Query, View 등 복잡한 쿼리 지원
- JOIN: 여러 테이블의 관련된 데이터를 결합할 수 있음
SELECT * FROM users JOIN orders ON users.id = orders.user_id;
- CTE (Common Table Expression): 임시 결과 집합을 정의해 가독성과 재사용성을 높임
WITH recent_orders AS (SELECT * FROM orders WHERE created_at > NOW() - INTERVAL '7 days') SELECT * FROM recent_orders WHERE total > 100;
- window function: 그룹 내 순위, 누적합 등 집계 계산을 행 단위로 수행
SELECT id, salary, RANK() OVER (ORDER BY salary DESC) AS rank FROM employee;
- sub query: 쿼리 안에 또 다른 쿼리를 중첩하여 결과를 조건으로 활용
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
- view: 자주 사용하는 쿼리를 가상 테이블로 정의해 재사용 가능
CREATE VIEW active_users AS SELECT * FROM users WHERE active = true;
- ACID 트랜잭션 지원을 통한 강력한 무결성을 보장하며, 내부적으로 MVCC를 사용하여 동시성 보장 및 락 경합 최소화
- 원자성 (Atomicity): 데이터베이스에 모두 반영되거나 전혀 반영되지 않아야 함
- 일관성 (Consistency): 트랜잭션이 실행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 함
- 독립성 (Isolation): 동시에 실행되는 트랜잭션이 서로 영향을 주지 않아야 함
- 지속성 (Durability): 성공적으로 완료된 트랜잭션의 결과가 영구적으로 반영되어야 함
- MVCC (Multi-Version Concurrency Control, 다중 버전 동시성 제어)를 통한 높은 동시성 처리 가능
- 하나의 레코드를 여러 버전으로 관리해 읽기 작업이 쓰기를 블로킹하지 않음
- 트랜잭션 ID (XID)를 통해 각 버전을 추적하며, 읽기 작업은 자신이 시작된 시점 기준으로 유효한 버전 참조해 락 경합 최소화
- 여러 사용자가 동시에 데이터를 액세스해도 읽기와 쓰기가 서로를 방해하지 않음
- autovacuum launcher 프로세스를 통해 불필요한 버전을 정리
- 다양한 형태의 고급 데이터 구조 지원
- UUID를 통한 전역 고유 식별자 저장
- 반정형 데이터 타입 JSON/JSONB을 통해 NoSQL 도큐먼트 저장 가능 (이진 포맷인 JSONB는 검색 및 인덱싱에 유리)
- HSTORE를 통한 key-value 쌍을 컬럼 하나에 저장
- 배열 데이터 타입 ARRAY를 통한 다중 값을 하나의 필드에 저장
- 기본으로 지원하는 B-Tree 외에도 풍부한 인덱스 제공
- B-Tree Index는 범위 검색 및 정렬 (
=, <, >, BETWEEN, ORDER BY)에 최적화되어 있으며, 다중 칼럼 인덱스 (multi-column index) 지원
- GIN (Generalized Inverted Index): 다중 키에 대한 역색인 구조로, 하나의 행에 여러 키를 저장하는 데이터에 대해 유리. JSON, ARRAY에 대한 키 기반 인덱싱 사용 가능
- GIST (Generalized Search Tree): 공간 및 범위 검색 등 비정형 데이터에 대한 인덱싱 적합
프로세스 기반 구조로 동작하며, 각 클라이언트 연결마다 backend process 프로세스를 생성
- postmaster (postgres): 메인 프로세스. 서버를 초기화하고 클라이언트 연결을 수신하여 각 요청에 대한 백엔드 프로세스 생성
- backend process (client backend): 각 클라이언트 연결마다 생성되는 세션 프로세스. SQL 파싱 → 실행 → 결과 반환 담당
- background writer (bgwriter): 공유 버퍼 내 변경된 페이지 (dirty buffer)를 주기적으로 디스크로 flush하여 I/O 부하 분산
- checkpointer: 주기적으로 데이터베이스 상태를 checkpoint로 기록하여 복구 시점을 단축
- walwriter: 변경 로그 (write-ahead log)를 디스크로 기록하여 트랜잭션의 Durability 보장
- autovacuum launcher: 오래된 MVCC 버전을 정리하고 통계 갱신 수행 (vaccum 및 analyze 자동화)
- stats collector (pg_stat): 쿼리, 테이블, 인덱스 사용량 등의 통계 수집
- archiver: WAL 파일을 외부 스토리지에 보관하여 PITR (Point-in-Time Recovery) 가능하게 함
- logical replication launcher: 논리적 복제 세션 관리 및 데이터 동기화 수행
- shared buffers: 모든 프로세스가 공유하는 영역으로, 디스크에서 읽은 페이지 (데이터 블록) 캐시
- WAL buffers: 트랜잭션 변경 로그 (WAL)를 디스크에 쓰기 전에 임시 저장
- work_mem: 정렬, 해시 조인 등 쿼리 실행 중에 필요한 임시 메모리 영역 (세션별로 할당)
- maintenace_work_mem: VACUUM, CREATE INDEX, ANALYZE 등 유지보수 작업 시에 사용하는 임시 메모리
- temp buffers: 세션 내 임시 테이블이나 임시 연산 결과 저장
- shared memory area: 프로세스 간 통신 (IPC)를 위한 영역. 세션 간 동기화 및 통계 데이터 공유에 사용
데이터를 논리적 계층 구조와 물리적 저장 구조로 나누어 관리
- logical hierarchy: 사용자가 인식하는 논리적인 데이터 계층 모델
- column (attribute): 데이터의 최소 단위. 특정 속성(attribute)을 표현하는 필드
- row (record): 여러 컬럼 값들의 집합으로, 논리적으로 한 개체(entity)를 나타냄
- table: 동일한 속성을 가진 행 (row)의 집합
- schema: 관련된 테이블, 뷰, 함수 등을 그룹화한 논리적 네임스페이스
- database: 여러 스키마로 구성된 하나의 독립적인 데이터베이스 인스턴스
- cluster: 하나의 PostgreSQL 서버 인스턴스가 관리하는 전체 데이터베이스 집합
- physical storage structure: 실제로 디스크에 물리적으로 저장되는 형태
- field: 데이터의 최소 저장 단위로, column의 물리적 표현
- record: 물리적으로 연속된 field들의 묶음으로, row의 물리적 표현
- file: 동일한 유형의 record들이 저장된 디스크 상의 단위로, 각 table은 하나 이상의 file로 표현
- tablespace: database 객체가 실재로 저장되는 물리적 디스크 경로로, 하나 이상의 data file로 구성
- block structure: 디스크 I/O 효율을 위해 데이터를 블록 단위로 관리
- block (page): 디스크에서 읽고 쓰는 최소 단위. 여러 record를 물리적으로 묶어 저장 (기본 크기는 8KB)
- blocking factor: 하나의 block에 저장되는 record의 개수. fixed-length record인 경우 (block size) / (record length)
- slotted page structure: variable-length record를 효율적으로 저장하기 위한 페이지 레이아웃
- block header: 페이지의 시작 부분에 위치하며, 페이지 메타데이터 저장
- slot array pointer: 헤더 바로 옆에 위치하며, 각 record의 오프셋 저장하는 배열. 페이지 시작 부분에서 record 영역 쪽으로 성장
- data area: record 데이터가 저장되며, 페이지 끝 부분에서 슬롯 배열 쪽으로 성장
- free space: slot array와 data area 사이의 남은 공간
- free space pointer: free space의 시작 위치 가리킴
- 파일 조직 (file organization): file 내 record가 디스크 내에 물리적으로 어떻게 저장되고 관리되는지를 정의하는 구조
- heap: record가 삽입 순서대로 저장되며, index가 없으면 전체 스캔 (sequential scan)으로 검색 수행
- heap file organization: 해시 함수를 이용해 bucket에 저장. 레코드 탐색에 비효율적이어서 대규모 데이터베이스에서는 거의 활용되지 않음
- B-Tree organization: PosgreSQL의 기본 인덱스 구조로, 대부분의 인덱스가 B-Tree 기반으로 생성됨
- 데이터가 정렬된 키 순서로 트리 형태로 저장되어 있음
- 루트 (root), 내부 노드 (internal node), 리프 노드 (leaf node)로 구성되며, 각 노드는 페이지 단위 (8KB)로 관리됨
- 리프 노드는 키와 튜플 위치 (TID)가 저장되어 있어, 인덱스를 통해 테이블의 특정 행으로 빠른 접근 가능 → O(logN)
- 트리 높이가 일정하게 유지되므로 삽입 및 삭제 시에도 균형을 유지하여 대용량 데이터에 대해서도 성능 보장
- 쓰기 (
INSERT, UPDATE, DELETE) 빈도가 높으면 리밸런싱 및 페이지 분할에 대한 오버헤드 발생
- 접근 방법 계층 (access method layer): PostgreSQL의 파일 조직을 추상화하여 공통 인터페이스로 다루는 구조
- Access Method (AM): 테이블과 인덱스가 데이터를 어떻게 저장하고 접근할지 정의한 모듈
- Table Access MEthod (TAM): 테이블의 저장 및 접근 방식 정의
- PostgreSQL 12에 TAM 커스텀마이징 지원 (
CREATE ACCESS METHOD)
- Index Access Method (IAM): 인덱스에 따른
SELECT|INSERT|DELETE 알고리즘 정의