Database normalization/denormalization pattern library. An extension skill for data-modeler that provides 1NF-BCNF criteria, functional dependency analysis, step-by-step normalization procedures, strategic denormalization patterns, and common domain ERD templates. Use when data modeling involves 'normalization', 'denormalization', 'ERD patterns', 'functional dependencies', 'table splitting', 'relationship design', etc. Note: DDL generation and query optimization are outside the scope of this ...
Scanned 9/7/2026
Install to Claude Code
npx -y skills add chodolmu/taskforge-pro --skill normalization-patterns --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Normalization Patterns?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/chodolmu-normalization-patterns)More formats (shields.io, HTML) on the badges page.
---
name: normalization-patterns
description: "Database normalization/denormalization pattern library. An extension skill for data-modeler that provides 1NF-BCNF criteria, functional dependency analysis, step-by-step normalization procedures, strategic denormalization patterns, and common domain ERD templates. Use when data modeling involves 'normalization', 'denormalization', 'ERD patterns', 'functional dependencies', 'table splitting', 'relationship design', etc. Note: DDL generation and query optimization are outside the scope of this skill."
---
# Normalization Patterns — Normalization/Denormalization Pattern Library
Normalization rules, denormalization strategies, and domain-specific ERD patterns used by the data-modeler agent during data modeling.
## Target Agent
`data-modeler` — Directly applies the normalization rules and ERD patterns from this skill to data model designs.
## Normalization Stage Identification & Transformation
### 1NF (First Normal Form)
**Rule**: Every column must contain atomic (indivisible) values.
| Violation Pattern | Problem | Solution |
|------------------|---------|----------|
| Multi-value column | `tags = "java,python,go"` | Separate table (M:N) |
| Repeating groups | `phone1, phone2, phone3` | Separate table (1:N) |
| Composite values | `address = "123 Main St, City, State"` | Split into street/city/state columns |
### 2NF (Second Normal Form)
**Prerequisite**: Satisfies 1NF
**Rule**: Remove partial functional dependencies — separate columns that depend on only part of a composite primary key.
| Violation Example | Dependency | Solution |
|------------------|------------|----------|
| `order_details(order_id, product_id, product_name, quantity)` | product_name depends only on product_id | Separate into products table |
### 3NF (Third Normal Form)
**Prerequisite**: Satisfies 2NF
**Rule**: Remove transitive functional dependencies — a non-key column must not determine another non-key column.
| Violation Example | Dependency | Solution |
|------------------|------------|----------|
| `employees(id, dept_id, dept_name, dept_head)` | dept_name, dept_head transitively depend on dept_id | Separate into departments table |
### BCNF (Boyce-Codd Normal Form)
**Rule**: Every determinant must be a candidate key.
| Violation Example | Problem | Solution |
|------------------|---------|----------|
| `enrollment(student, course, professor)` where professor -> course | Professor is a determinant but not a candidate key | Separate into professor-course table |
## Normalization Decision Flowchart
```
Data Analysis
├─ Atomic value violation? -> 1NF transformation
├─ Composite key & partial dependency? -> 2NF transformation
├─ Transitive dependency? -> 3NF transformation
├─ Non-candidate-key determinant? -> BCNF transformation
└─ Performance requirements -> Review strategic denormalization
```
## Strategic Denormalization Patterns
### When to Denormalize?
- When the read-to-write ratio is very high
- Frequent queries requiring 5+ JOINs
- When real-time aggregation/statistics are needed
- Dashboard/report-specific data
### Denormalization Pattern Catalog
| Pattern | Description | Suitable For | Trade-offs |
|---------|-------------|-------------|------------|
| **Derived column** | Store computed values (`total_price`) | Frequent sum lookups | Requires sync on update |
| **Duplicated column** | Copy frequently used FK target columns | Avoiding JOINs | Data inconsistency risk |
| **Pre-joined table** | Materialize join results as physical table | Reports/dashboards | Storage space, update complexity |
| **History snapshot** | Preserve point-in-time data (`order_address`) | Storing address at time of order | Storage space |
| **Counter column** | `likes_count`, `comments_count` | Real-time count display | Concurrency handling |
| **JSON/JSONB** | Unstructured extension data | Settings, metadata | Indexing limitations |
## Common Domain ERD Patterns
### E-Commerce
```
users ──1:N──> orders ──1:N──> order_items
│ │
└──1:N──> addresses products
└──1:N──> reviews ──N:1──────┘
│
products ──N:M──> categories (via product_categories)
products ──1:N──> product_images
products ──1:N──> product_variants
```
Core tables:
- `users` (id, email, name, password_hash, created_at)
- `products` (id, name, description, base_price, status)
- `orders` (id, user_id, status, total, shipping_address_snapshot)
- `order_items` (id, order_id, product_id, variant_id, quantity, unit_price)
### SaaS Multi-Tenant
```
tenants ──1:N──> users ──N:M──> roles (via user_roles)
│ │
└──1:N──> subscriptions permissions ──N:M──> roles
└──1:N──> [domain tables] (tenant_id FK)
```
Key point: Include `tenant_id` in all business tables; apply RLS (Row Level Security)
### Social Network
```
users ──N:M──> users (via follows: follower_id, following_id)
│
└──1:N──> posts ──1:N──> comments
│ └──N:M──> tags (via post_tags)
│ └──1:N──> likes (user_id + post_id UNIQUE)
└──1:N──> messages (sender_id, receiver_id)
```
### CMS/Blog
```
users ──1:N──> posts ──N:M──> tags (via post_tags)
│
└──1:N──> comments (self-referencing: parent_id)
└──1:N──> media
└──1:1──> post_meta (SEO, OG tags, etc.)
```
## Relationship Patterns
### 1:1 Relationship
- Large table splitting (frequently used columns vs rarely used columns)
- Optional extension (`user` + `user_profile`)
- Implementation: FK + UNIQUE constraint
### 1:N Relationship
- Most common relationship type
- Self-referencing: category trees, comment threads (`parent_id`)
- Implementation: FK on the child table
### M:N Relationship
- Junction table required
- Junction table may include additional attributes (`created_at`, `role`, `quantity`)
- Naming: `{table1}_{table2}` or a meaningful name (`enrollments`)
## Common Column Patterns
### Default Timestamps
Include in all tables:
- `id` — UUID or BIGINT AUTO_INCREMENT
- `created_at` — TIMESTAMPTZ DEFAULT NOW()
- `updated_at` — TIMESTAMPTZ, auto-updated via trigger
### Soft Delete
- `deleted_at` — TIMESTAMPTZ NULL (NULL means not deleted)
- All queries include `WHERE deleted_at IS NULL` condition
- Enables restoration and serves as audit trail
### Status Management
- `status` — ENUM or VARCHAR
- State transition rules must be documented (which states can transition to which)
- If history is needed, use a separate `status_history` table
### Internationalization
- Strategy 1: Column extension (`name_ko`, `name_en`, `name_ja`)
- Strategy 2: Translation table (`product_translations`: product_id, locale, name, description)
- Strategy 2 recommended (no schema changes needed when adding languages)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!