常用擴充套件
PostgreSQL 的擴充機制讓它能處理各種專業領域的需求。本篇介紹常用的擴充套件。
一、 擴充管理基礎
sql
-- 查看可用擴充
SELECT * FROM pg_available_extensions;
-- 安裝擴充
CREATE EXTENSION IF NOT EXISTS extension_name;
-- 查看已安裝擴充
SELECT * FROM pg_extension;
-- 更新擴充
ALTER EXTENSION extension_name UPDATE;
-- 移除擴充
DROP EXTENSION extension_name;二、 pg_trgm:模糊搜尋
Trigram 相似度搜尋,支援模糊匹配和 LIKE 索引。
sql
CREATE EXTENSION pg_trgm;
-- 建立 GIN 索引
CREATE INDEX idx_products_name_trgm ON products USING GIN (name gin_trgm_ops);相似度搜尋
sql
-- 計算相似度
SELECT similarity('PostgreSQL', 'Postgres'); -- 0.625
-- 相似度搜尋
SELECT name, similarity(name, 'PostgreSQL') AS sim
FROM products
WHERE name % 'PostgreSQL' -- 相似度 > 0.3
ORDER BY sim DESC;
-- 調整相似度閾值
SET pg_trgm.similarity_threshold = 0.5;LIKE 索引加速
sql
-- 現在 LIKE '%keyword%' 也能用索引!
SELECT * FROM products WHERE name LIKE '%database%';
SELECT * FROM products WHERE name ILIKE '%Database%';三、 PostGIS:地理空間
處理地理位置資料的必備擴充。
sql
CREATE EXTENSION postgis;
-- 建立表
CREATE TABLE locations (
id SERIAL PRIMARY KEY,
name TEXT,
geom GEOMETRY(Point, 4326) -- WGS84 座標系
);
-- 插入資料(經度, 緯度)
INSERT INTO locations (name, geom) VALUES
('台北101', ST_SetSRID(ST_MakePoint(121.5645, 25.0339), 4326)),
('高雄85大樓', ST_SetSRID(ST_MakePoint(120.2922, 22.6096), 4326));
-- 建立空間索引
CREATE INDEX idx_locations_geom ON locations USING GIST (geom);距離查詢
sql
-- 找出 1 公里內的地點
SELECT name, ST_Distance(
geom::geography,
ST_MakePoint(121.5, 25.0)::geography
) AS distance_m
FROM locations
WHERE ST_DWithin(
geom::geography,
ST_MakePoint(121.5, 25.0)::geography,
1000 -- 1000 公尺
);區域查詢
sql
-- 找出多邊形範圍內的地點
SELECT name FROM locations
WHERE ST_Within(geom, ST_GeomFromText(
'POLYGON((121 25, 122 25, 122 26, 121 26, 121 25))',
4326
));四、 pg_stat_statements:效能監控
追蹤查詢執行統計。
sql
-- 需要設定 postgresql.conf
-- shared_preload_libraries = 'pg_stat_statements'
CREATE EXTENSION pg_stat_statements;
-- 查看最耗時的查詢
SELECT
calls,
total_exec_time::INTEGER AS total_ms,
mean_exec_time::INTEGER AS mean_ms,
LEFT(query, 80) AS query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
-- 重設統計
SELECT pg_stat_statements_reset();五、 uuid-ossp:UUID 生成
sql
CREATE EXTENSION "uuid-ossp";
-- 生成 UUID v4(隨機)
SELECT uuid_generate_v4();
-- d7c4e7b0-3a1f-4c5e-9d2f-1b3c4d5e6f7a
-- 用於主鍵
CREATE TABLE users (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
name TEXT
);替代方案:gen_random_uuid()
PostgreSQL 13+ 內建 gen_random_uuid(),不需要擴充:
sql
SELECT gen_random_uuid();
CREATE TABLE users (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT
);六、 pgcrypto:加密
sql
CREATE EXTENSION pgcrypto;
-- 雜湊
SELECT crypt('password123', gen_salt('bf'));
-- $2a$06$...
-- 驗證密碼
SELECT crypt('password123', stored_hash) = stored_hash;
-- 加密
SELECT pgp_sym_encrypt('secret data', 'encryption_key');
-- 解密
SELECT pgp_sym_decrypt(encrypted_data, 'encryption_key');七、 hstore:鍵值對
簡單的 key-value 儲存。
sql
CREATE EXTENSION hstore;
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT,
attributes HSTORE
);
INSERT INTO products (name, attributes) VALUES
('Laptop', 'brand => HP, ram => 16GB, ssd => 512GB');
-- 查詢
SELECT name, attributes->'brand' AS brand FROM products;
-- 條件查詢
SELECT * FROM products WHERE attributes @> 'brand => HP';
-- 轉換為 JSONB
SELECT hstore_to_jsonb(attributes) FROM products;TIP
現代開發建議使用 JSONB 取代 hstore,功能更豐富。
八、 TimescaleDB:時序資料
專門處理時間序列資料。
bash
# 安裝(需要另外安裝)
apt install timescaledb-postgresql-16sql
CREATE EXTENSION timescaledb;
-- 建立普通表
CREATE TABLE metrics (
time TIMESTAMPTZ NOT NULL,
device_id INTEGER,
temperature FLOAT,
humidity FLOAT
);
-- 轉換為 Hypertable
SELECT create_hypertable('metrics', 'time');
-- 插入資料
INSERT INTO metrics VALUES
(NOW(), 1, 25.5, 60.2),
(NOW() - INTERVAL '1 hour', 1, 24.8, 58.5);
-- 時間聚合查詢
SELECT
time_bucket('1 hour', time) AS hour,
device_id,
AVG(temperature) AS avg_temp
FROM metrics
WHERE time > NOW() - INTERVAL '1 day'
GROUP BY hour, device_id;自動壓縮
sql
-- 設定壓縮
ALTER TABLE metrics SET (
timescaledb.compress,
timescaledb.compress_segmentby = 'device_id'
);
-- 壓縮舊資料
SELECT add_compression_policy('metrics', INTERVAL '7 days');九、 pg_cron:定時任務
sql
CREATE EXTENSION pg_cron;
-- 每小時執行
SELECT cron.schedule('refresh_stats', '0 * * * *',
'REFRESH MATERIALIZED VIEW CONCURRENTLY hourly_stats');
-- 每天凌晨 3 點
SELECT cron.schedule('cleanup', '0 3 * * *',
'DELETE FROM logs WHERE created_at < NOW() - INTERVAL ''30 days''');
-- 查看任務
SELECT * FROM cron.job;
-- 取消任務
SELECT cron.unschedule('refresh_stats');十、 其他實用擴充
pg_partman:分區管理
sql
CREATE EXTENSION pg_partman;
SELECT create_parent(
p_parent_table => 'public.events',
p_control => 'created_at',
p_interval => 'daily'
);pgvector:向量搜尋
用於 AI/ML 嵌入向量相似度搜尋:
sql
CREATE EXTENSION vector;
CREATE TABLE items (
id SERIAL PRIMARY KEY,
embedding vector(384) -- 384 維向量
);
-- 餘弦相似度搜尋
SELECT * FROM items
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 10;pg_hint_plan:查詢提示
sql
CREATE EXTENSION pg_hint_plan;
-- 強制使用特定索引
SELECT /*+ IndexScan(users idx_users_email) */ *
FROM users WHERE email = 'alice@example.com';十一、 擴充安全性
sql
-- 只允許 superuser 安裝擴充
-- 在 pg_hba.conf 限制 superuser 連線
-- 信任的擴充清單
# postgresql.conf
trusted_extensions = 'pg_trgm,uuid-ossp'總結
| 擴充 | 用途 |
|---|---|
| pg_trgm | 模糊搜尋、LIKE 索引 |
| PostGIS | 地理空間資料 |
| pg_stat_statements | 查詢效能分析 |
| uuid-ossp | UUID 生成 |
| pgcrypto | 加密與雜湊 |
| TimescaleDB | 時序資料 |
| pg_cron | 定時任務 |
| pgvector | 向量搜尋 (AI/ML) |
PostgreSQL 的擴充生態讓它幾乎可以處理任何類型的資料需求。
進階挑戰
- 安裝
pg_trgm擴充,為產品名稱實作模糊搜尋功能 - 使用
pgvector擴充建立一個簡單的語義搜尋系統 - 設定
pg_cron每天凌晨 3 點自動刷新物化檢視