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

496 lines
10 KiB
Markdown

---
id: db-postgres-extensions
title: Postgres Extensions — pgvector / TimescaleDB / Citus
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [database, postgres, extensions, vibe-coding]
tech_stack: { language: "PostgreSQL", applicable_to: ["Backend"] }
applied_in: []
aliases: [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
```sql
-- 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;
```
### pgvector (vector search)
```sql
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)
```sql
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)
```sql
CREATE EXTENSION citus;
SELECT create_distributed_table('orders', 'tenant_id');
-- 자동 sharding by tenant_id
```
→ [[DB_Sharding_Strategies]].
### PostGIS (geo)
```sql
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;
```
### pg_trgm (fuzzy search)
```sql
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)
```sql
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)
```sql
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)
```sql
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 분석)
```sql
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)
```sql
-- 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)
```sql
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)
```sql
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)
```sql
-- 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)
```sql
CREATE EXTENSION pg_jsonschema;
CREATE TABLE events (
data JSONB CHECK (jsonschema_is_valid('
{"type":"object","required":["type"],"properties":{"type":{"type":"string"}}}
', data))
);
```
### pgaudit (compliance)
```sql
CREATE EXTENSION pgaudit;
ALTER SYSTEM SET pgaudit.log = 'write,ddl';
SELECT pg_reload_conf();
```
→ Detailed audit log.
### pg_hint_plan (force plan)
```sql
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
```bash
# Docker
docker run -d \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
pgvector/pgvector:pg16
# Or 직접 install
apt install postgresql-16-pgvector
```
### Extension version 관리
```sql
-- 현재 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)
```bash
pg_repack -d mydb -t orders
```
→ VACUUM FULL 의 zero-downtime alternative.
→ [[DB_Vacuum_Autovacuum]].
### Useful 시작 set
```sql
-- 시작 시 활성
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
```sql
-- Vector + cron + JSON
SELECT cron.schedule('embed-new-docs', '*/10 * * * *', $$
UPDATE docs SET embedding = embed(content)
WHERE embedding IS NULL
$$);
```
### Custom extension (자체 build)
```c
// 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
```bash
pg_dump --extensions=all -d mydb > backup.sql
# Or specific
pg_dump --extension=pg_cron --extension=vector -d mydb
```
### Test
```ts
// 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 확인.
- 점진 도입.
## 🔗 관련 문서
- [[DB_pgvector_Production]]
- [[DB_Time_Series_Patterns]]
- [[DB_Sharding_Strategies]]