Designing postgres schemas
Skill pumarogie/claude-postgres-skills/skills/designing-postgres-schemas
Production Postgres survival skills for Claude Code — schema design, safe migrations, query performance, connection pooling, autovacuum/bloat, and queue/partitioning patterns.
npx -y skills add pumarogie/claude-postgres-skills --skill designing-postgres-schemasAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 15 days oldThe repository was created 15 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when creating tables, choosing primary keys, picking column types, deciding on foreign keys, or reaching for a jsonb column in Postgres.
SKILL.md
2.7 KB, 586 tokens by cl100k_base, as published. Nobody here has run it
Designing Postgres Schemas
Overview
The schema is the hardest thing to change after deployment. Get primary keys, timestamp types, and the read/write shape right up front — design iteratively from the queries your app actually runs, not from an abstract entity diagram.
When to Use
- Creating a new table or adding columns.
- Choosing a primary key strategy.
- Deciding a timestamp / id column type.
- Considering foreign keys with cascading deletes.
- Tempted to store a blob of fields in
jsonb.
Not for: query tuning (see writing-performant-queries) or changing an existing live schema (see
writing-safe-migrations).
Quick Reference
| Decision | Do this | Why |
|---|---|---|
| Primary key | Identity column (auto-int) or built-in uuid | Both index well; always give every table a PK |
| Timestamps | timestamptz — never timestamp | Stores UTC + offset; avoids timezone corruption |
| Foreign keys | FK + ON DELETE CASCADE at low volume | Data correctness; use caution at high write volume |
| Fast-moving fields | jsonb escape hatch when moving fast | Flexible, but you lose constraints/indexing guarantees |
Pattern
CREATE TABLE tasks (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, -- always have a PK
tenant_id uuid NOT NULL,
status text NOT NULL,
payload jsonb, -- escape hatch; flag the tradeoff
created_at timestamptz NOT NULL DEFAULT now(), -- timestamptz, not timestamp
updated_at timestamptz NOT NULL DEFAULT now()
);
Design Approach
Build iteratively. Start with a rough table, then write the queries the app needs and let them drive the columns and indexes. For each table ask:
- Is this high-read or high-write?
- What are the common filter columns? (those want indexes)
- Which columns update most often? (hot updates → dead tuples → see
tuning-autovacuum-and-bloat)
Normalization (1NF/2NF/3NF) reduces duplication but can fight query efficiency — denormalize deliberately when reads demand it, not by accident.
Common Mistakes
timestampinstead oftimestamptz— silent timezone bugs later.- No primary key — breaks joins, replication, and
FOR UPDATE SKIP LOCKEDpatterns. - Cascading deletes on a high-volume table — one delete can lock and rewrite huge child sets.
jsonbeverything — you forfeit constraints and cheap indexed lookups; use real columns for anything you filter or join on.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.