UNPKG

@incidental/project-templates

Version:

Claude Code template library for JavaScript projects with framework auto-detection

226 lines (187 loc) 5.27 kB
--- name: database-schema description: Design and implement database schemas with proper relationships, constraints, and migrations allowed-tools: Read, Write, Edit, Grep, Glob, Bash --- # Database Schema Skill Design and implement database schemas following best practices. ## When to Use Use this skill when you need to: - Design database schema - Create migration files - Define models/entities - Set up relationships - Add indexes and constraints ## What This Skill Does This skill generates database schemas including: 1. **Schema design** with proper normalization 2. **Migration files** for version control 3. **Model definitions** using ORMs (Prisma, TypeORM, Sequelize) 4. **Relationships** (one-to-one, one-to-many, many-to-many) 5. **Constraints** (unique, foreign keys, check constraints) 6. **Indexes** for query performance ## Schema Design Principles ### Normalization - First Normal Form (1NF): Atomic values - Second Normal Form (2NF): No partial dependencies - Third Normal Form (3NF): No transitive dependencies ### Naming Conventions - Tables: plural, lowercase with underscores (e.g., `users`, `blog_posts`) - Columns: lowercase with underscores (e.g., `created_at`, `first_name`) - Primary keys: `id` or `table_name_id` - Foreign keys: `referenced_table_id` (e.g., `user_id`) - Junction tables: combine table names (e.g., `users_roles`) ## Prisma Schema Example ```prisma // User model model User { id String @id @default(cuid()) email String @unique name String? password String role Role @default(USER) posts Post[] profile Profile? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([email]) @@map("users") } // Profile model (one-to-one) model Profile { id String @id @default(cuid()) bio String? avatar String? userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("profiles") } // Post model (one-to-many) model Post { id String @id @default(cuid()) title String content String published Boolean @default(false) authorId String author User @relation(fields: [authorId], references: [id], onDelete: Cascade) tags Tag[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([authorId]) @@index([published]) @@map("posts") } // Tag model (many-to-many) model Tag { id String @id @default(cuid()) name String @unique posts Post[] @@map("tags") } // Enum enum Role { USER ADMIN MODERATOR } ``` ## SQL Migration Example ```sql -- Create users table CREATE TABLE users ( id VARCHAR(36) PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), password VARCHAR(255) NOT NULL, role VARCHAR(50) DEFAULT 'USER', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_email (email) ); -- Create profiles table CREATE TABLE profiles ( id VARCHAR(36) PRIMARY KEY, bio TEXT, avatar VARCHAR(255), user_id VARCHAR(36) NOT NULL UNIQUE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Create posts table CREATE TABLE posts ( id VARCHAR(36) PRIMARY KEY, title VARCHAR(255) NOT NULL, content TEXT NOT NULL, published BOOLEAN DEFAULT FALSE, author_id VARCHAR(36) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE, INDEX idx_author (author_id), INDEX idx_published (published) ); -- Create tags table CREATE TABLE tags ( id VARCHAR(36) PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE ); -- Create posts_tags junction table (many-to-many) CREATE TABLE posts_tags ( post_id VARCHAR(36) NOT NULL, tag_id VARCHAR(36) NOT NULL, PRIMARY KEY (post_id, tag_id), FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE, FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE ); ``` ## Relationship Types ### One-to-One ```prisma model User { profile Profile? } model Profile { user User @relation(fields: [userId], references: [id]) userId String @unique } ``` ### One-to-Many ```prisma model User { posts Post[] } model Post { author User @relation(fields: [authorId], references: [id]) authorId String } ``` ### Many-to-Many ```prisma model Post { tags Tag[] } model Tag { posts Post[] } ``` ## Best Practices ### Indexing - Index foreign keys - Index frequently queried columns - Composite indexes for multi-column queries - Don't over-index (slows writes) ### Constraints - Use NOT NULL where appropriate - Add unique constraints for unique data - Use check constraints for validation - Set proper ON DELETE behavior (CASCADE, SET NULL, RESTRICT) ### Data Types - Use appropriate types (INT, VARCHAR, TEXT, TIMESTAMP, etc.) - Use ENUM for fixed sets of values - Use JSON for flexible data (sparingly) - Consider UUID vs auto-increment IDs ### Migrations - Never edit existing migrations - Create new migration for each change - Test migrations before production - Include both up and down migrations - Back up data before running migrations