From scaffolding
Provides schema design principles, index strategy, migration safety, and query analysis for database optimization. Useful when designing tables, writing migrations, or diagnosing slow queries.
How this skill is triggered — by the user, by Claude, or both
Slash command
/scaffolding:database-optimizationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Form | Use When |
| Form | Use When |
|---|---|
| 1NF | Always (atomic values) |
| 2NF | Most tables |
| 3NF | Transactional data |
| Denormalized | Read-heavy, reporting |
| Type | Use Case |
|---|---|
| B-Tree | Default, range queries |
| Hash | Exact match only |
| GIN (Postgres) | Full-text, JSONB, arrays |
| Partial | Subset of rows |
| Composite | Multi-column queries |
Index type names vary by engine (e.g. GIN/GiST/BRIN are Postgres-specific; MySQL/SQLite expose a different set). Treat engine-specific rows as examples.
| Issue | Symptom | Solution |
|---|---|---|
| Missing index | Sequential scan | Add index |
| N+1 queries | Many similar queries | Eager loading |
| Over-fetching | SELECT * | Select specific columns |
| No pagination | Large result sets | Add LIMIT/OFFSET |
| Cartesian join | Exploding rows | Fix JOIN conditions |
npm run build -- --analyze - Bundle analysislighthouse - Performance auditpy-spy - CPU profilingmemory_profiler - Memory analysisEXPLAIN ANALYZE - Query analysis| Setting | Development | Production |
|---|---|---|
| Min connections | 1 | 5 |
| Max connections | 5 | 20-50 |
| Idle timeout | 30s | 300s |
| Max lifetime | 1800s | 3600s |
Pool size formula: (cores * 2) + disk_spindles. Always use pooling in production.
| Element | Convention | Example |
|---|---|---|
| Tables | snake_case, plural | users, order_items |
| Columns | snake_case | first_name, created_at |
| Primary Key | id | id |
| Foreign Key | {table}_id | user_id, order_id |
| Indexes | ix_{table}_{columns} | ix_users_email |
Illustrative — this is one team's SQLAlchemy/Postgres setup shown as a concrete example. Substitute your ORM, driver, and schema conventions. The schema-design, indexing, and query-analysis guidance above is the engine-agnostic, reusable part.
<your-database-module>.py)from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
engine = create_async_engine(
DATABASE_URL, # postgresql+asyncpg://...
echo=False, future=True,
pool_size=5, max_overflow=10,
pool_recycle=3600, # Recycle connections after 1 hour
pool_pre_ping=True, # Detect stale connections
)
async_session_maker = async_sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)
Session dependency (commit-on-success, rollback-on-error):
async def get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session_maker() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
All models inherit from the shared declarative Base and follow these patterns:
| Convention | Pattern | Example |
|---|---|---|
| Primary key | String(36), UUID as string | id: Mapped[str] = mapped_column(String(36), primary_key=True) |
| Timestamps | DateTime(timezone=True) + utc_now | created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) |
| Foreign keys | Explicit ondelete policy | ForeignKey("projects.id", ondelete="CASCADE") |
| Nullable FK | ondelete="SET NULL" | ForeignKey("users.id", ondelete="SET NULL") |
| Indexes | On FKs and query columns | index=True on project_id, created_at, github_id |
| Type hints | Mapped[] with mapped_column | SQLAlchemy 2.0 declarative style |
| Relationships | TYPE_CHECKING guard for imports | Avoids circular imports between modules |
| Table | Model | Key Fields |
|---|---|---|
projects | Project | id, path (unique), name, created_at |
task_refs | TaskRef | id, project_id (FK), conversation_id, session_id, created_by (FK) |
users | User | id (uuid4), github_id (unique), github_login, avatar_url |
user_projects | UserProject | user_id (FK), project_id (FK), role, UniqueConstraint |
# Parent side - cascade delete orphans
tasks: Mapped[list["TaskRef"]] = relationship(
"TaskRef", back_populates="project", cascade="all, delete-orphan"
)
# Child side
project: Mapped["Project"] = relationship("Project", back_populates="tasks")
psycopg2 (strips +asyncpg from URL)pg_advisory_lock(1573678) prevents concurrent migrationsmain.py validates ORM vs DB schema on startup, logs warnings{hash}_{description}.py with upgrade() and downgrade()env.py: Required for autogenerate supportupgrade() and downgrade() functionsnpx claudepluginhub komluk/scaffolding --plugin scaffoldingDesigns database schemas, indexing strategies, query optimization, and migration patterns for SQL and NoSQL databases. Use for schema design, N+1 fixes, normalization, and performance tuning.
Provides best practices for database schema design, query optimization, migrations, indexing, N+1 avoidance, pagination, and transactions across PostgreSQL, MySQL, Oracle, SQLite. Use for schema design, queries, or migrations.
Guides SQL database design, query optimization, and migration safety. Use when writing queries, designing schemas, or planning zero-downtime migrations.