算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
postgresql【设计与创意】PostgreSQL schema design, query optimization, indexing, and administration. Use when writing schemas, queries, migrations, or mentions PostgreSQL, Postgres, JSONB, partitioning, RLS, CTEs, window functions, EXPLAIN ANALYZE, or connection pooling.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
| Need | Use | Avoid |
|---|---|---|
| Primary key | BIGINT GENERATED ALWAYS AS IDENTITY | SERIAL, BIGSERIAL |
| Timestamps | TIMESTAMPTZ | TIMESTAMP (loses timezone) |
| Text | TEXT | VARCHAR(n) unless constraint needed |
| Money | NUMERIC(precision, scale) | MONEY, FLOAT |
| Boolean | BOOLEAN with NOT NULL DEFAULT | nullable booleans |
| JSON | JSONB | JSON (no indexing), text JSON |
| UUID | gen_random_uuid() (PG13+) | uuid-ossp extension |
| IP addresses | INET / CIDR | text |
| Ranges | TSTZRANGE, INT4RANGE, etc. | pair of columns |
NOT NULL on every column unless NULL has business meaningCHECK constraints for domain rules at DB levelEXCLUDE constraints for range overlaps: EXCLUDE USING gist (room WITH =, during WITH &&)created_at TIMESTAMPTZ NOT NULL DEFAULT now()updated_at with trigger, never trust app layer aloneBIGINT PKs — cheaper JOINs than UUID, better index locality| Type | Use When |
|---|---|
| B-tree (default) | Equality, range, sorting, LIKE 'prefix%' |
| GIN | JSONB (@>, ?, ?&), arrays, full-text (tsvector) |
| GiST | Geometry, ranges, full-text (smaller but slower than GIN) |
| BRIN | Large tables with natural ordering (timestamps, serial IDs) |
Index rules:
WHERE status = 'active' — smaller, fasterINCLUDE (col) — avoids heap lookupON (lower(email)) — for function-based WHERESELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0-- GIN index for containment queries
CREATE INDEX ON items USING gin (metadata);
SELECT * FROM items WHERE metadata @> '{"status": "active"}';
-- Expression index for specific key access
CREATE INDEX ON items ((metadata->>'category'));
SELECT * FROM items WHERE metadata->>'category' = 'electronics';
Prefer typed columns over JSONB for frequently queried, well-structured data. Use JSONB for truly dynamic/variable attributes.
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) before optimizingWHERE for function wrappingrows removed by filter → index doesn't match predicateCTE is an optimization fence before PG12; use MATERIALIZED/NOT MATERIALIZED hints (PG12+)EXISTS over IN for correlated subqueriesLATERAL JOIN when subquery needs outer row referenceWHERE id > $last ORDER BY id LIMIT $n) over OFFSETUse when table exceeds ~100M rows or needs TTL purge:
RANGE — time-series (by month/year), most commonLIST — categorical (by region, tenant)HASH — even distribution when no natural keyPartition key must be in every unique/PK constraint. Create indexes on partitions, not parent.
SELECT ... FOR UPDATE SKIP LOCKED — job queue / work claiming patternpg_advisory_xact_lock(key)SELECT * FROM pg_stat_activity WHERE wait_event_type = 'Lock'-- Weighted tsvector column with trigger
ALTER TABLE articles ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce(title,'')), 'A') ||
setweight(to_tsvector('english', coalesce(body,'')), 'B')
) STORED;
CREATE INDEX ON articles USING gin (search_vector);
SELECT * FROM articles WHERE search_vector @@ websearch_to_tsquery('english', $1);
Key postgresql.conf parameters (adjust for available RAM):
shared_buffers = 25% of RAMeffective_cache_size = 75% of RAMwork_mem = RAM / max_connections / 4 (start 4-16MB)maintenance_work_mem = 256MB-1GBrandom_page_cost = 1.1 for SSD (default 4.0 is for HDD)Always pool in production. Direct connections cost ~10MB each.
transaction mode for most workloadsstatement mode if no session-level features (prepared statements, temp tables, advisory locks)pg_stat_statements extension — find slow queries by total time, not just durationpg_stat_user_tables — check n_dead_tup for vacuum needsautovacuum tuning: lower thresholds for hot tablesSELECT sum(heap_blks_hit) / sum(heap_blks_hit + heap_blks_read) FROM pg_statio_user_tables — should be > 99%| Anti-Pattern | Fix |
|---|---|
SERIAL / BIGSERIAL for PKs | BIGINT GENERATED ALWAYS AS IDENTITY |
| No FK indexes | Add index on every FK column |
OFFSET pagination | Cursor-based: WHERE id > $last |
SELECT * | List needed columns |
TIMESTAMP without timezone | TIMESTAMPTZ |
Functions in WHERE (lower(col)) | Expression index or citext extension |
| Storing structured data as text | JSONB with GIN index |
| Long-running transactions | Keep txns short, use idle_in_transaction_session_timeout |