Files
2nd/10_Wiki/Topics/Coding/DB_Postgres_Extensions.md
T
2026-05-09 22:47:42 +09:00

10 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
db-postgres-extensions Postgres Extensions — pgvector / TimescaleDB / Citus Coding draft B conceptual 2026-05-09 2026-05-09
database
postgres
extensions
vibe-coding
language applicable_to
PostgreSQL
Backend
Postgres extensions
pgvector
TimescaleDB
Citus
PostGIS
pg_cron
pg_partman

Postgres Extensions

Postgres = "swiss army knife". Extension 가 거의 모든 use case. pgvector / TimescaleDB / Citus / PostGIS / pg_cron 등.

📖 핵심 개념

  • Extension: SQL + C code module.
  • CREATE EXTENSION: 활성.
  • Cloud RDS / Aurora / Neon = 대부분 지원.
  • Self-host = 직접 install.

💻 코드 패턴

자주 쓰는 extension

-- Vector
CREATE EXTENSION vector;        -- pgvector

-- Time-series
CREATE EXTENSION timescaledb;    -- TimescaleDB

-- Distributed
CREATE EXTENSION citus;          -- Citus

-- Geo
CREATE EXTENSION postgis;        -- PostGIS

-- Crypto
CREATE EXTENSION pgcrypto;       -- 해시, 암호

-- UUID
CREATE EXTENSION "uuid-ossp";    -- UUID 생성

-- Cron
CREATE EXTENSION pg_cron;        -- DB 안 cron

-- Stats
CREATE EXTENSION pg_stat_statements;  -- query 분석
CREATE EXTENSION auto_explain;         -- slow query log

-- HLL (probabilistic)
CREATE EXTENSION hll;            -- HyperLogLog

-- Trigram (fuzzy search)
CREATE EXTENSION pg_trgm;

-- JSON 강력
CREATE EXTENSION pg_jsonschema;

-- Async / queue
CREATE EXTENSION pgmq;           -- message queue

-- Compression
CREATE EXTENSION pg_lz;
CREATE EXTENSION vector;

CREATE TABLE docs (
    id BIGSERIAL,
    content TEXT,
    embedding VECTOR(1536)
);

CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);

-- Search
SELECT * FROM docs ORDER BY embedding <=> $1::vector LIMIT 5;

DB_pgvector_Production.

TimescaleDB (time-series)

CREATE EXTENSION timescaledb;

CREATE TABLE metrics (
    ts TIMESTAMPTZ NOT NULL,
    device_id TEXT,
    cpu DOUBLE PRECISION
);

SELECT create_hypertable('metrics', 'ts', chunk_time_interval => INTERVAL '1 day');

-- 자동 partition + 압축 + retention

DB_Time_Series_Patterns.

Citus (sharding)

CREATE EXTENSION citus;

SELECT create_distributed_table('orders', 'tenant_id');
-- 자동 sharding by tenant_id

DB_Sharding_Strategies.

PostGIS (geo)

CREATE EXTENSION postgis;

CREATE TABLE places (
    id SERIAL PRIMARY KEY,
    name TEXT,
    location GEOGRAPHY(POINT, 4326)
);

INSERT INTO places (name, location) VALUES (
    'Tower',
    ST_GeographyFromText('POINT(127.0 37.5)')
);

-- 1km 안 가까운
SELECT * FROM places
WHERE ST_DWithin(location, ST_GeographyFromText('POINT(127.0 37.5)'), 1000);

-- 거리
SELECT name, ST_Distance(location, ST_GeographyFromText('POINT(127.0 37.5)')) AS dist
FROM places ORDER BY dist LIMIT 10;
CREATE EXTENSION pg_trgm;

CREATE INDEX users_name_trgm ON users USING GIN (name gin_trgm_ops);

-- Similar names
SELECT name, similarity(name, 'alice') AS sim
FROM users
WHERE name % 'alice'  -- pg_trgm operator
ORDER BY sim DESC LIMIT 10;

-- Partial match
SELECT * FROM users WHERE name ILIKE '%al%';  -- 빠름 (with trgm index)

pg_cron (scheduled jobs)

CREATE EXTENSION pg_cron;

-- 매일 오전 9시 cleanup
SELECT cron.schedule('cleanup-old-data', '0 9 * * *', $$
    DELETE FROM events WHERE created_at < NOW() - INTERVAL '90 days'
$$);

-- 매 5분
SELECT cron.schedule('sync-cache', '*/5 * * * *', 'CALL refresh_cache()');

-- List
SELECT * FROM cron.job;

-- Unschedule
SELECT cron.unschedule('cleanup-old-data');

→ Application-level cron 대안.

pgcrypto (encryption)

CREATE EXTENSION pgcrypto;

-- Hash
SELECT crypt('password', gen_salt('bf'));

-- Verify
SELECT crypt('password', stored_hash) = stored_hash;

-- Random
SELECT gen_random_uuid();
SELECT gen_random_bytes(16);

-- Encrypt
SELECT pgp_sym_encrypt('secret', 'password');
SELECT pgp_sym_decrypt(encrypted, 'password');

pgmq (message queue in PG)

CREATE EXTENSION pgmq;

SELECT pgmq.create('my_queue');

-- Send
SELECT pgmq.send('my_queue', '{"order_id": 42}');

-- Read (with VT — 30s lock)
SELECT * FROM pgmq.read('my_queue', 30, 1);
-- {msg_id, message, ...}

-- Delete (ack)
SELECT pgmq.delete('my_queue', 1);

-- Archive
SELECT pgmq.archive('my_queue', 1);

→ Postgres = light queue. SQS / RabbitMQ alternative.

pg_stat_statements (query 분석)

CREATE EXTENSION pg_stat_statements;

-- Top slow queries
SELECT
    query,
    calls,
    total_exec_time / 1000 AS total_seconds,
    mean_exec_time AS avg_ms,
    rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC LIMIT 20;

DB_Postgres_EXPLAIN.

auto_explain (slow query log)

-- postgresql.conf
shared_preload_libraries = 'auto_explain'

ALTER SYSTEM SET auto_explain.log_min_duration = '500ms';
ALTER SYSTEM SET auto_explain.log_analyze = on;
ALTER SYSTEM SET auto_explain.log_buffers = on;
SELECT pg_reload_conf();

→ Slow query 자동 EXPLAIN log.

pg_partman (자동 partition)

CREATE EXTENSION pg_partman;

SELECT partman.create_parent(
    p_parent_table => 'public.events',
    p_control => 'created_at',
    p_type => 'native',
    p_interval => 'monthly',
    p_premake => 3
);

-- Maintenance (매 시간)
SELECT partman.run_maintenance_proc();

→ Automatic partition creation + drop.

plv8 (JS in DB)

CREATE EXTENSION plv8;

CREATE FUNCTION my_function(input TEXT)
RETURNS TEXT AS $$
    return input.toUpperCase();
$$ LANGUAGE plv8;

SELECT my_function('hello');  -- 'HELLO'

→ JavaScript stored procedure.

Foreign Data Wrapper (FDW)

-- Postgres → Postgres
CREATE EXTENSION postgres_fdw;

CREATE SERVER remote_pg
    FOREIGN DATA WRAPPER postgres_fdw
    OPTIONS (host 'remote.example.com', dbname 'app');

CREATE FOREIGN TABLE remote_users
    (id UUID, email TEXT)
    SERVER remote_pg
    OPTIONS (schema_name 'public', table_name 'users');

SELECT * FROM remote_users;

→ Postgres → MySQL / S3 / file 도 가능.

pg_jsonschema (JSON validation)

CREATE EXTENSION pg_jsonschema;

CREATE TABLE events (
    data JSONB CHECK (jsonschema_is_valid('
        {"type":"object","required":["type"],"properties":{"type":{"type":"string"}}}
    ', data))
);

pgaudit (compliance)

CREATE EXTENSION pgaudit;

ALTER SYSTEM SET pgaudit.log = 'write,ddl';
SELECT pg_reload_conf();

→ Detailed audit log.

pg_hint_plan (force plan)

CREATE EXTENSION pg_hint_plan;

/*+ IndexScan(orders orders_user_idx) */
SELECT * FROM orders WHERE user_id = $1;

→ Planner hint. Last resort.

Cloud 의 extension 지원

RDS Postgres: 100+ extension.
Aurora: 비슷.
Supabase: pgvector, pg_cron, etc 강.
Neon: pgvector, postgis.
Cloud SQL: 표준 set.

→ Provider docs 검사.

Self-host

# Docker
docker run -d \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  pgvector/pgvector:pg16

# Or 직접 install
apt install postgresql-16-pgvector

Extension version 관리

-- 현재 version
SELECT * FROM pg_extension WHERE extname = 'vector';

-- Update
ALTER EXTENSION vector UPDATE TO '0.7.0';

-- Available versions
SELECT * FROM pg_available_extension_versions WHERE name = 'vector';

pg_repack (online table rewrite)

pg_repack -d mydb -t orders

→ VACUUM FULL 의 zero-downtime alternative.

DB_Vacuum_Autovacuum.

Useful 시작 set

-- 시작 시 활성
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS pg_trgm;

Combo (modern app)

- pgvector (RAG)
- pg_cron (scheduled tasks)
- pgmq (light queue)
- pg_trgm (search)
- pg_stat_statements (monitoring)
- pgaudit (compliance)

→ Postgres 만으로 큰 stack 가능.

Multi-extension query

-- Vector + cron + JSON
SELECT cron.schedule('embed-new-docs', '*/10 * * * *', $$
    UPDATE docs SET embedding = embed(content)
    WHERE embedding IS NULL
$$);

Custom extension (자체 build)

// my_extension.c
#include "postgres.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(my_function);
Datum my_function(PG_FUNCTION_ARGS) {
    int32 arg = PG_GETARG_INT32(0);
    PG_RETURN_INT32(arg * 2);
}

→ C 작성 → DB 안 native function.

Extension as source of truth

Cloud-native:
- pgvector + RAG
- pg_cron + jobs
- pgmq + queue
- pg_partman + time-series

→ Postgres = monolith DB. 작은 팀 = 강력.

When NOT to use

- 큰 throughput / 분산 — Citus / Yugabyte
- Real-time analytics (PB) — ClickHouse / Druid
- 강력 search — Elasticsearch
- Real-time messaging — Kafka
- 큰 vector (1B+) — Vespa / Milvus

Migration path

Start: Postgres + extensions (작은 stack).
Grow: 일부 = 별 system (Kafka, ClickHouse).
End: Specialized stack.

→ Premature specialization X.
   PG 가 90% case 충분.

Backup with extensions

pg_dump --extensions=all -d mydb > backup.sql

# Or specific
pg_dump --extension=pg_cron --extension=vector -d mydb

Test

// Test 가 같은 extension 가짐
beforeAll(async () => {
  await db.execute(`CREATE EXTENSION IF NOT EXISTS pg_trgm`);
});

🤔 의사결정 기준

사용 추천 extension
Vector search pgvector
Time-series TimescaleDB
Sharding Citus
Geo PostGIS
Search pg_trgm + tsvector
Cron pg_cron
Queue pgmq
Crypto pgcrypto

안티패턴

  • Cloud 가 안 지원 — extension 가정: 검사.
  • Major upgrade 시 extension 호환 X: 검증.
  • Extension 너무 많이: 의존 복잡.
  • 자체 patch — upstream 무시: 유지 어려움.
  • Production 가 latest minor: 검증.

🤖 LLM 활용 힌트

  • Postgres + 5 ~ 10 extension = 큰 stack.
  • pgvector + pg_cron + pgmq = mini SaaS.
  • Cloud 의 supported list 확인.
  • 점진 도입.

🔗 관련 문서