claude-code/claude-zh/skills/postgres-patterns/SKILL.md

147 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: postgres-patterns
description: PostgreSQL 資料庫模式,涵蓋查詢優化、架構設計、索引及安全性。基於 Supabase 最佳實踐。
---
# PostgreSQL 模式 (PostgreSQL Patterns)
PostgreSQL 最佳實踐快速參考指南。如需更深入的建議,請使用 `database-reviewer` Agent。
## 何時啟用
- 編寫 SQL 查詢或進行資料遷移 (Migrations)。
- 設計資料庫架構 (Schemas)。
- 排除查詢緩慢的故障。
- 實作資料列層級安全性 (Row Level Security, RLS)。
- 設置連接池。
## 快速參考
### 索引速查表
| 查詢模式 | 索引類型 | 範例 |
|--------------|------------|---------|
| `WHERE col = value` | B-tree (預設) | `CREATE INDEX idx ON t (col)` |
| `WHERE col > value` | B-tree | `CREATE INDEX idx ON t (col)` |
| `WHERE a = x AND b > y` | 複合索引 (Composite) | `CREATE INDEX idx ON t (a, b)` |
| `WHERE jsonb @> '{}'` | GIN | `CREATE INDEX idx ON t USING gin (col)` |
| `WHERE tsv @@ query` | GIN | `CREATE INDEX idx ON t USING gin (col)` |
| 時間序列區間 (Ranges) | BRIN | `CREATE INDEX idx ON t USING brin (col)` |
### 資料型別快速對比
| 使用場景 | 正確型別 | 應避免使用 |
|----------|-------------|-------|
| ID 欄位 | `bigint` | `int`, 隨機 UUID |
| 字串 | `text` | `varchar(255)` |
| 時間戳記 | `timestamptz` | `timestamp` |
| 金額 | `numeric(10,2)` | `float` |
| 旗標 (Flags) | `boolean` | `varchar`, `int` |
### 常見模式
**複合索引排序規則:**
```sql
-- 先放等值 (Equality) 欄位,再放範圍 (Range) 欄位
CREATE INDEX idx ON orders (status, created_at);
-- 適用於WHERE status = 'pending' AND created_at > '2024-01-01'
```
**覆蓋索引 (Covering Index)**
```sql
CREATE INDEX idx ON users (email) INCLUDE (name, created_at);
-- 針對 SELECT email, name, created_at可避免回表查詢 (Table lookup)
```
**部分索引 (Partial Index)**
```sql
CREATE INDEX idx ON users (email) WHERE deleted_at IS NULL;
-- 體積較小,僅包含活躍中的使用者
```
**RLS 策略(優化版):**
```sql
CREATE POLICY policy ON orders
USING ((SELECT auth.uid()) = user_id); -- 務必包裹在 SELECT 中!
```
**更新或插入 (UPSERT)**
```sql
INSERT INTO settings (user_id, key, value)
VALUES (123, 'theme', 'dark')
ON CONFLICT (user_id, key)
DO UPDATE SET value = EXCLUDED.value;
```
**游標分頁 (Cursor Pagination)**
```sql
SELECT * FROM products WHERE id > $last_id ORDER BY id LIMIT 20;
-- O(1) 複雜度;相比之下 OFFSET 為 O(n)
```
**隊列處理 (Queue Processing)**
```sql
UPDATE jobs SET status = 'processing'
WHERE id = (
SELECT id FROM jobs WHERE status = 'pending'
ORDER BY created_at LIMIT 1
FOR UPDATE SKIP LOCKED
) RETURNING *;
```
### 反模式偵測
```sql
-- 找出未建立索引的外鍵 (Unindexed Foreign Keys)
SELECT conrelid::regclass, a.attname
FROM pg_constraint c
JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY(c.conkey)
WHERE c.contype = 'f'
AND NOT EXISTS (
SELECT 1 FROM pg_index i
WHERE i.indrelid = c.conrelid AND a.attnum = ANY(i.indkey)
);
-- 找出查詢緩慢的 SQL
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
WHERE mean_exec_time > 100
ORDER BY mean_exec_time DESC;
-- 檢查資料表膨脹 (Bloat) 情況
SELECT relname, n_dead_tup, last_vacuum
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC;
```
### 配置範本
```sql
-- 連線限制(視記憶體大小調整)
ALTER SYSTEM SET max_connections = 100;
ALTER SYSTEM SET work_mem = '8MB';
-- 超時設定
ALTER SYSTEM SET idle_in_transaction_session_timeout = '30s';
ALTER SYSTEM SET statement_timeout = '30s';
-- 監控
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- 安全性預設值
REVOKE ALL ON SCHEMA public FROM public;
SELECT pg_reload_conf();
```
## 相關連結
- Agent: `database-reviewer` - 完整的資料庫審查工作流。
- 技能: `clickhouse-io` - ClickHouse 分析模式。
- 技能: `backend-patterns` - API 與後端模式。
---
*源自 [Supabase Agent Skills](https://github.com/supabase/agent-skills) (MIT License)*