database-design · spencerpauly — Claude Code skill: what it does, how to install
Designs relational database schemas, foreign keys, indexes, and constraints from raw requirements, with output tailored for SQL, Prisma, or Drizzle.
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a claude-codeWhat database-design does
The skill extracts core entities from product specifications and maps them into SQL tables. It sets foreign key relationships with explicit ON DELETE rules, enforces TIMESTAMPTZ for dates, and picks UUID or BIGSERIAL depending on whether IDs are public or internal. It also translates the resulting tables into Prisma models or Drizzle schemas.
The workflow enforces third normal form (3NF) from the start. Denormalization is reserved only for verified bottlenecks. Common architectural patterns are baked in, including soft deletes via deleted_at, audit logs, tree hierarchies, and junction tables for tags.
The skill explicitly advises against indexing tables with fewer than 1000 rows or columns with low cardinality. That prevents wasted disk and write overhead.
What it helps with
- Map entity relationships into normalized SQL tables
- Define indexing strategies for frequent filters and join keys
- Generate ORM schemas for Prisma and Drizzle with timezone support
- Implement soft delete and audit log patterns in PostgreSQL
Example prompts for the agent
- Design a database schema for an issue tracker with teams, projects, and task assignments
- Add indexes and foreign key constraints for these orders and line items tables in Drizzle
- Set up a hierarchical category schema with audit logging
How to install database-design
1Skills CLI (Vercel)
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a claude-code2Manually: put the files in place
~/.claude/skills/database-design/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/database-design/
1Skills CLI (Vercel)
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a codex2Manually: put the files in place
.agents/skills/database-design/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a cursor2Manually: put the files in place
.cursor/skills/database-design/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install spencerpauly/awesome-cursor-skills database-design2Manually: put the files in place
.github/skills/database-design/SKILL.md1Skills CLI (Vercel)
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a gemini-cli2Platform CLI
gemini skills install https://github.com/spencerpauly/awesome-cursor-skills --path resources/database-designManually: put the files in place
.devin/skills/database-design/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about database-design
How to install database-design in Claude Code?
Run npx skills add spencerpauly/awesome-cursor-skills --skill database-design -a claude-code. You can also place the file directly at ~/.claude/skills/database-design/SKILL.md.
What does the database-design skill do?
It guides the assistant through schema modeling: picking primary keys, setting relationship cardinality, choosing timestamps, and writing clean SQL or ORM definitions.
When does this skill avoid creating database indexes?
It advises against indexing tables under 1000 rows, rarely queried columns, and low-cardinality attributes like booleans or three-value statuses.
Source text
SKILL.md · CC0-1.0
---
name: database-design
description: Design database schemas — tables, relationships, indexes, constraints, and ORM setup. Covers relational design, normalization, and common patterns.
user-invocable: true
---
# Database Design
Design a database schema from requirements.
## Workflow
### 1. Identify Entities
From the requirements, extract the core entities (nouns):
- Users, Teams, Projects, Tasks, Comments, etc.
- Each entity becomes a table
### 2. Define Relationships
| Relationship | Implementation |
|-------------|----------------|
| One-to-one | Foreign key with unique constraint, or embed in same table |
| One-to-many | Foreign key on the "many" side |
| Many-to-many | Junction/join table |
| Self-referential | Foreign key pointing to same table (e.g. `parent_id`) |
### 3. Design the Schema
For each table:
```sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
avatar_url TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
```
### 4. Apply Best Practices
**Primary keys:**
- Use `UUID` for distributed systems or public-facing IDs
- Use `SERIAL`/`BIGSERIAL` for internal-only IDs (faster joins)
**Timestamps:**
- Always add `created_at` and `updated_at`
- Use `TIMESTAMPTZ` (with timezone), never `TIMESTAMP`
**Naming:**
- Tables: plural snake_case (`users`, `project_members`)
- Columns: singular snake_case (`user_id`, `created_at`)
- Indexes: `idx_<table>_<columns>` (`idx_users_email`)
**Constraints:**
- `NOT NULL` on everything unless it's genuinely optional
- `UNIQUE` on natural keys (email, slug, external IDs)
- `REFERENCES` with `ON DELETE` behavior (CASCADE, SET NULL, RESTRICT)
- `CHECK` constraints for enums or value ranges
### 5. Add Indexes
```sql
-- For columns you filter/sort by frequently
CREATE INDEX idx_projects_owner_id ON projects(owner_id);
-- For unique lookups
CREATE UNIQUE INDEX idx_users_email ON users(email);
-- Composite for common query patterns
CREATE INDEX idx_tasks_project_status ON tasks(project_id, status);
```
**When to index:**
- Foreign keys (almost always)
- Columns in WHERE clauses
- Columns in ORDER BY
- Columns in JOIN conditions
**When NOT to index:**
- Small tables (<1000 rows)
- Columns with low cardinality (boolean, status with 3 values)
- Columns that are rarely queried
### 6. ORM Setup
**Prisma:**
```prisma
model User {
id String @id @default(uuid())
email String @unique
name String
projects Project[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("users")
}
```
**Drizzle:**
```typescript
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email').notNull().unique(),
name: text('name').notNull(),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
});
```
## Common Patterns
**Soft deletes:** Add `deleted_at TIMESTAMPTZ` instead of actually deleting rows
**Audit log:** Separate `audit_events` table with `entity_type`, `entity_id`, `action`, `actor_id`, `payload`
**Tags/labels:** Junction table (`task_tags`) with `task_id` + `tag_id`
**Tree/hierarchy:** `parent_id` self-reference, or materialized path (`/1/4/7/`)
**Polymorphic associations:** Use `entity_type` + `entity_id` columns (avoid if possible, prefer separate FKs)
## Tips
- Start normalized (3NF), denormalize only when you have measured performance problems
- Don't store derived data unless you have a caching/invalidation strategy
- Use database enums or check constraints for status fields, not free-text
- Always think about what happens when you delete a parent record
© spencerpauly · CC0-1.0 · spencerpauly/awesome-cursor-skills
Similar skills
All skills for Data and databases →database-design by other authors comes first.