db-schema
Design a database schema for a given domain or feature. Auto-invoke when the user says "design the schema for", "what tables do we need for", "model the database for", or "ER design for X".
SKILL.mdskills/db-schema/SKILL.md
GitHubDB Schema Skill
Design a normalised, production-ready database schema for: $ARGUMENTS
Step 1 — Read the DB Process File
Always read @~/.claude/process/db_process.md before generating anything.
Step 2 — Identify Entities and Relationships
List:
- All entities (nouns in the domain)
- Relationships between them with cardinality (1:1, 1:N, M:N)
- Key attributes per entity
Present this entity list before writing any DDL. Wait for approval.
Step 3 — Define the Schema
For each table:
-- Table: <table_name>
-- Purpose: <what this represents>
CREATE TABLE <table_name> (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-- or: id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
-- FK columns next
<fk_col> BIGINT UNSIGNED NOT NULL,
-- domain columns
...
-- audit columns always last
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL -- include only if soft-delete applies
CONSTRAINT fk_<table>_<ref> FOREIGN KEY (<fk_col>) REFERENCES <ref_table>(id) ON DELETE RESTRICT
);
Rules (from db_process.md)
- Normalise to 3NF — denormalise only with a documented reason written as a SQL comment
- Use
DECIMAL(19, 4)for monetary values — neverFLOATorDOUBLE - Use
TIMESTAMPfor datetimes, always stored in UTC - Boolean columns prefixed with
is_orhas_ - Join tables for M:N:
<table_a>_<table_b>(alphabetical order, e.g.order_products) - Never store comma-separated values in a column
Step 4 — Define Indexes
After tables, list all indexes with justification:
-- Indexes for <table_name>
CREATE INDEX idx_<table>_<col> ON <table>(<col>); -- FK index (always)
CREATE INDEX idx_<table>_<col> ON <table>(<col>); -- query: WHERE status = ?
CREATE UNIQUE INDEX uq_<table>_<col> ON <table>(<col>); -- uniqueness constraint
For each index, write a comment explaining which query pattern it supports.
Step 5 — Flag Design Decisions
Call out explicitly:
- Any denormalisation decisions and why
- Soft-delete strategy (if used): which tables, how it's enforced at app layer
- UUID vs auto-increment choice and rationale
- Any columns that look like they might grow into a separate table later
- Multi-tenancy: if applicable, identify which tables need
tenant_idand how it's indexed
Step 6 — Write Migration File
Generate a migration file in the project's migration format:
- Laravel →
database/migrations/<timestamp>_create_<table>_table.php - Node.js → check for Knex, Prisma, or TypeORM and match the format
- Go → check for golang-migrate and produce
.sqlmigration files
Output
- Write schema to
docs/db/<domain>-schema.mdwith the ER description + DDL - Write the migration file(s) to the appropriate location
- Print a summary: tables created, relationships, indexes added, decisions flagged