Marketplace

data-modeling

Use when designing data models, database schemas, or choosing between modeling approaches. Covers dimensional modeling, star schema, data vault, entity-relationship design, and schema evolution.

allowed_tools: Read, Glob, Grep

$ Installer

git clone https://github.com/melodic-software/claude-code-plugins /tmp/claude-code-plugins && cp -r /tmp/claude-code-plugins/plugins/systems-design/skills/data-modeling ~/.claude/skills/claude-code-plugins

// tip: Run this command in your terminal to install the skill


name: data-modeling description: Use when designing data models, database schemas, or choosing between modeling approaches. Covers dimensional modeling, star schema, data vault, entity-relationship design, and schema evolution. allowed-tools: Read, Glob, Grep

Data Modeling

Comprehensive guide to data modeling techniques for operational databases, data warehouses, and analytical systems.

When to Use This Skill

  • Designing database schemas
  • Choosing between modeling approaches
  • Building data warehouses
  • Planning schema evolution
  • Understanding trade-offs in data models
  • Designing for analytics vs operations

Data Modeling Fundamentals

Types of Data Models

Data Model Categories:

1. Conceptual Model
   Purpose: Business understanding
   Audience: Business stakeholders
   Content: Entities, relationships, business rules
   Detail: High-level, no implementation details

2. Logical Model
   Purpose: Structure definition
   Audience: Data architects
   Content: Tables, columns, keys, relationships
   Detail: Database-agnostic design

3. Physical Model
   Purpose: Implementation
   Audience: Database engineers
   Content: Indexes, partitions, storage
   Detail: Database-specific optimization

Model Evolution:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                              โ”‚
โ”‚  Business         Conceptual        Logical       Physical   โ”‚
โ”‚  Requirements โ”€โ”€โ–บ Model        โ”€โ”€โ–บ Model     โ”€โ”€โ–บ Model      โ”‚
โ”‚                                                              โ”‚
โ”‚  "Customers       Customer โ”€โ”€โ”€โ”€โ”€โ–บ  customers    customers    โ”‚
โ”‚   make orders"    Order           โ”œโ”€โ”€ id        โ”œโ”€โ”€ id PK   โ”‚
โ”‚                   โ””โ”€โ”€< makes      โ”œโ”€โ”€ name      โ”œโ”€โ”€ name    โ”‚
โ”‚                                   โ””โ”€โ”€ email     โ”œโ”€โ”€ email   โ”‚
โ”‚                                                 โ””โ”€โ”€ idx_*   โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Operational vs Analytical

Operational (OLTP) vs Analytical (OLAP):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      OLTP                                   โ”‚
โ”‚            (Online Transaction Processing)                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Purpose:    Run the business                               โ”‚
โ”‚ Workload:   Many small transactions                        โ”‚
โ”‚ Model:      Normalized (3NF)                               โ”‚
โ”‚ Optimize:   Write performance, consistency                 โ”‚
โ”‚ Users:      Applications, services                         โ”‚
โ”‚ Example:    INSERT new order, UPDATE inventory             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      OLAP                                   โ”‚
โ”‚            (Online Analytical Processing)                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Purpose:    Analyze the business                           โ”‚
โ”‚ Workload:   Few complex queries                            โ”‚
โ”‚ Model:      Denormalized (star/snowflake)                  โ”‚
โ”‚ Optimize:   Read performance, aggregation                  โ”‚
โ”‚ Users:      Analysts, BI tools                             โ”‚
โ”‚ Example:    SUM(sales) GROUP BY region, month              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

When to Use Each:
โ”œโ”€โ”€ OLTP: User-facing applications, real-time operations
โ”œโ”€โ”€ OLAP: Reporting, dashboards, machine learning
โ””โ”€โ”€ Hybrid: Some systems need both (HTAP)

Normalization

Normal Forms

Database Normalization:

1NF (First Normal Form):
โ”œโ”€โ”€ Eliminate repeating groups
โ”œโ”€โ”€ Create separate table for related data
โ”œโ”€โ”€ Identify each row with primary key
โ””โ”€โ”€ Each cell contains single value

Example (SQL Server - PascalCase):
โŒ Orders (Id, Item1, Item2, Item3)
โœ“ Orders (Id, ...) + OrderItems (OrderId, ItemId)

2NF (Second Normal Form):
โ”œโ”€โ”€ Meet 1NF requirements
โ”œโ”€โ”€ Remove partial dependencies
โ””โ”€โ”€ Non-key columns depend on entire primary key

Example (SQL Server - PascalCase):
โŒ OrderItems (OrderId, ProductId, ProductName)
โœ“ OrderItems (OrderId, ProductId) + Products (ProductId, ProductName)

3NF (Third Normal Form):
โ”œโ”€โ”€ Meet 2NF requirements
โ”œโ”€โ”€ Remove transitive dependencies
โ””โ”€โ”€ Non-key columns depend only on primary key

Example (SQL Server - PascalCase):
โŒ Orders (Id, CustomerId, CustomerCity)
โœ“ Orders (Id, CustomerId) + Customers (Id, City)

BCNF (Boyce-Codd Normal Form):
โ”œโ”€โ”€ Meet 3NF requirements
โ”œโ”€โ”€ Every determinant is a candidate key
โ””โ”€โ”€ Handles multi-valued dependencies

Higher Normal Forms (4NF, 5NF):
โ”œโ”€โ”€ Handle complex multi-valued dependencies
โ”œโ”€โ”€ Rarely used in practice
โ””โ”€โ”€ Can lead to over-normalization

When to Denormalize

Normalization Trade-offs:

Normalized (3NF):
โ”œโ”€โ”€ Pros: Data integrity, no redundancy, smaller storage
โ”œโ”€โ”€ Cons: Complex joins, slower reads
โ””โ”€โ”€ Use: OLTP, write-heavy workloads

Denormalized:
โ”œโ”€โ”€ Pros: Faster reads, simpler queries
โ”œโ”€โ”€ Cons: Redundancy, update anomalies, larger storage
โ””โ”€โ”€ Use: OLAP, read-heavy workloads

Denormalization Triggers:
1. Read performance is critical
2. Write frequency is low
3. Data changes infrequently
4. Queries frequently join same tables
5. Aggregations are common

Controlled Denormalization Patterns:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Pattern: Summary Tables                                      โ”‚
โ”‚ Keep normalized + materialized aggregates                   โ”‚
โ”‚                                                              โ”‚
โ”‚  orders โ”€โ”€โ”                                                 โ”‚
โ”‚  items  โ”€โ”€โ”ผโ”€โ”€โ–บ daily_sales_summary (materialized)          โ”‚
โ”‚  productsโ”€โ”˜                                                 โ”‚
โ”‚                                                              โ”‚
โ”‚ Best of both: Write to normalized, read from summary        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Dimensional Modeling

Star Schema

Star Schema:
Central fact table surrounded by dimension tables.

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  dim_date    โ”‚
                    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
                    โ”‚ date_key  PK โ”‚
                    โ”‚ date         โ”‚
                    โ”‚ month        โ”‚
                    โ”‚ quarter      โ”‚
                    โ”‚ year         โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ dim_product  โ”‚    โ”‚  fact_sales  โ”‚    โ”‚ dim_customer โ”‚
โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
โ”‚ product_key PKโ”‚โ—„โ”€โ”€โ”‚ date_key  FK โ”‚โ”€โ”€โ”€โ–บโ”‚ customer_key PKโ”‚
โ”‚ product_name โ”‚    โ”‚ product_key FKโ”‚    โ”‚ customer_nameโ”‚
โ”‚ category     โ”‚    โ”‚ customer_key FKโ”‚   โ”‚ segment      โ”‚
โ”‚ brand        โ”‚    โ”‚ store_key  FK โ”‚    โ”‚ region       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚ quantity     โ”‚
                    โ”‚ revenue      โ”‚           โ”‚
                    โ”‚ cost         โ”‚           โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                           โ”‚            โ”‚  dim_store   โ”‚
                           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
                                       โ”‚ store_key  PKโ”‚
                                       โ”‚ store_name   โ”‚
                                       โ”‚ city         โ”‚
                                       โ”‚ state        โ”‚
                                       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Star Schema Benefits:
โ”œโ”€โ”€ Simple queries (few joins)
โ”œโ”€โ”€ Optimized for aggregation
โ”œโ”€โ”€ Intuitive for business users
โ”œโ”€โ”€ Works well with BI tools
โ””โ”€โ”€ Predictable query performance

Fact Table Types:
โ”œโ”€โ”€ Transaction: One row per event (sale, click)
โ”œโ”€โ”€ Periodic Snapshot: One row per period (daily balance)
โ”œโ”€โ”€ Accumulating Snapshot: Track progress (order lifecycle)
โ””โ”€โ”€ Factless: Events without measures (attendance)

Snowflake Schema

Snowflake Schema:
Normalized dimensions (dimensions have sub-dimensions).

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  dim_date    โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ dim_category โ”‚โ—„โ”€โ”€โ”€โ”‚ dim_product  โ”‚    โ”‚ dim_customer โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚                    โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”‚      โ”‚
        โ”‚           โ”‚  fact_sales  โ”‚            โ”‚      โ”‚
        โ”‚           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚      โ”‚
        โ”‚                  โ”‚                    โ”‚      โ”‚
        โ”‚           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚           โ”‚  dim_store   โ”‚     โ”‚ dim_segment โ”‚
        โ”‚           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                  โ”‚
        โ”‚           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚           โ”‚  dim_city    โ”‚
        โ”‚           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Star vs Snowflake:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Factor          โ”‚ Star              โ”‚ Snowflake            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Query simplicityโ”‚ Simpler           โ”‚ More complex         โ”‚
โ”‚ Query speed     โ”‚ Faster (fewer joins)โ”‚ Slower             โ”‚
โ”‚ Storage         โ”‚ More (redundancy) โ”‚ Less (normalized)    โ”‚
โ”‚ Maintenance     โ”‚ Easier            โ”‚ More complex         โ”‚
โ”‚ BI tool support โ”‚ Better            โ”‚ May need modeling    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recommendation: Prefer star schema unless storage is critical concern.

Slowly Changing Dimensions

Slowly Changing Dimensions (SCD):
How to handle dimension changes over time.

Type 0: Retain Original
โ””โ”€โ”€ Never update dimension
โ””โ”€โ”€ Use for: Attributes that shouldn't change

Type 1: Overwrite
โ””โ”€โ”€ Update in place, lose history
โ””โ”€โ”€ Use for: Corrections, non-historical attributes

Type 2: Add New Row (Most Common)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ customer_keyโ”‚ customer_id โ”‚ address      โ”‚ valid_from โ”‚ valid_to โ”‚ currentโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1001        โ”‚ C123        โ”‚ 123 Oak St   โ”‚ 2020-01-01 โ”‚ 2023-06-30โ”‚ false  โ”‚
โ”‚ 1002        โ”‚ C123        โ”‚ 456 Pine Ave โ”‚ 2023-07-01 โ”‚ 9999-12-31โ”‚ true   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ””โ”€โ”€ New surrogate key, track validity period
โ””โ”€โ”€ Use for: Full history required

Type 3: Add New Column
โ””โ”€โ”€ Previous and current value columns
โ””โ”€โ”€ Use for: Limited history (just previous)

Type 4: History Table
โ””โ”€โ”€ Current in main table, history in separate table
โ””โ”€โ”€ Use for: Frequent changes, large dimensions

Type 6: Hybrid (1+2+3)
โ””โ”€โ”€ Combines approaches for flexibility
โ””โ”€โ”€ Use for: Complex requirements

Data Vault

Data Vault Architecture

Data Vault Modeling:
Enterprise data warehouse pattern for agility and auditability.

Components:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         DATA VAULT                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                              โ”‚
โ”‚  HUBS (Business Keys)                                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                     โ”‚
โ”‚  โ”‚ hub_customer       โ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ hub_key     PK โ”‚  โ† Surrogate key                   โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ customer_id    โ”‚  โ† Business key                    โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ load_date      โ”‚  โ† When loaded                     โ”‚
โ”‚  โ”‚ โ””โ”€โ”€ source         โ”‚  โ† Where from                      โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                     โ”‚
โ”‚                                                              โ”‚
โ”‚  LINKS (Relationships)                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                     โ”‚
โ”‚  โ”‚ link_customer_orderโ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ link_key    PK โ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ hub_customer_fkโ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ hub_order_fk   โ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ load_date      โ”‚                                     โ”‚
โ”‚  โ”‚ โ””โ”€โ”€ source         โ”‚                                     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                     โ”‚
โ”‚                                                              โ”‚
โ”‚  SATELLITES (Descriptive Data)                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                     โ”‚
โ”‚  โ”‚ sat_customer_detailsโ”‚                                    โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ hub_customer_fkโ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ load_date   PK โ”‚  โ† Part of PK                      โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ name           โ”‚  โ† Descriptive attributes          โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ email          โ”‚                                     โ”‚
โ”‚  โ”‚ โ”œโ”€โ”€ hash_diff      โ”‚  โ† Change detection                โ”‚
โ”‚  โ”‚ โ””โ”€โ”€ source         โ”‚                                     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                     โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Data Vault Benefits:
โ”œโ”€โ”€ Full audit trail (all changes tracked)
โ”œโ”€โ”€ Source system agnostic
โ”œโ”€โ”€ Parallel loading possible
โ”œโ”€โ”€ Handles schema changes gracefully
โ””โ”€โ”€ Good for regulatory requirements

Data Vault Challenges:
โ”œโ”€โ”€ Complex queries (many joins)
โ”œโ”€โ”€ Requires presentation layer
โ”œโ”€โ”€ Steep learning curve
โ”œโ”€โ”€ More storage than star schema
โ””โ”€โ”€ Not suitable for direct BI access

When to Use Data Vault

Data Vault Decision Matrix:

Use Data Vault When:
โ”œโ”€โ”€ Multiple source systems with different schemas
โ”œโ”€โ”€ Regulatory requirements for audit trails
โ”œโ”€โ”€ Schema changes are frequent
โ”œโ”€โ”€ Historical accuracy is critical
โ”œโ”€โ”€ Large enterprise with complex data landscape
โ””โ”€โ”€ Data integration from acquisitions

Use Star Schema When:
โ”œโ”€โ”€ Simpler reporting requirements
โ”œโ”€โ”€ Single source system
โ”œโ”€โ”€ Fast query performance priority
โ”œโ”€โ”€ Business users query directly
โ”œโ”€โ”€ Smaller scale, simpler needs
โ””โ”€โ”€ Quick time to value needed

Hybrid Approach:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                              โ”‚
โ”‚  Source โ”€โ”€โ–บ Data Vault โ”€โ”€โ–บ Star Schema โ”€โ”€โ–บ BI Tools         โ”‚
โ”‚  Systems    (Raw Vault)   (Presentation)  (Reports)         โ”‚
โ”‚                                                              โ”‚
โ”‚  Benefits:                                                   โ”‚
โ”‚  โ”œโ”€โ”€ Raw vault: Full history, audit                        โ”‚
โ”‚  โ”œโ”€โ”€ Star schema: Query performance                         โ”‚
โ”‚  โ””โ”€โ”€ Decoupled: Change raw without breaking reports         โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Schema Evolution

Schema Evolution Patterns

Schema Evolution Strategies:

1. Additive Changes (Safest)
   โ”œโ”€โ”€ Add new columns with defaults
   โ”œโ”€โ”€ Add new tables
   โ””โ”€โ”€ Add new indexes

   Safe: Does not break existing queries

   ALTER TABLE users ADD COLUMN phone VARCHAR(20) DEFAULT NULL;

2. Non-Breaking Changes
   โ”œโ”€โ”€ Widen column types (VARCHAR(50) โ†’ VARCHAR(100))
   โ”œโ”€โ”€ Remove NOT NULL constraint
   โ””โ”€โ”€ Add optional foreign keys

   Usually safe, verify with testing

3. Breaking Changes (Dangerous)
   โ”œโ”€โ”€ Rename columns/tables
   โ”œโ”€โ”€ Remove columns
   โ”œโ”€โ”€ Change column types
   โ””โ”€โ”€ Add NOT NULL without default

   Requires migration strategy

Migration Patterns:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Pattern: Expand-Contract                                     โ”‚
โ”‚                                                              โ”‚
โ”‚ Phase 1 (Expand):                                           โ”‚
โ”‚ โ”œโ”€โ”€ Add new column (name_new)                               โ”‚
โ”‚ โ”œโ”€โ”€ Write to both old and new                               โ”‚
โ”‚ โ””โ”€โ”€ Backfill new column                                     โ”‚
โ”‚                                                              โ”‚
โ”‚ Phase 2 (Migrate):                                          โ”‚
โ”‚ โ”œโ”€โ”€ Update readers to use new column                        โ”‚
โ”‚ โ””โ”€โ”€ Verify all systems migrated                             โ”‚
โ”‚                                                              โ”‚
โ”‚ Phase 3 (Contract):                                         โ”‚
โ”‚ โ””โ”€โ”€ Remove old column                                       โ”‚
โ”‚                                                              โ”‚
โ”‚ Timeline: Days to weeks per phase                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Versioning Strategies

Schema Versioning:

1. Single Schema (Most Common)
   โ”œโ”€โ”€ One schema, evolve in place
   โ”œโ”€โ”€ Use migrations (Flyway, Liquibase)
   โ””โ”€โ”€ All applications use same version

2. Multi-Version Schema
   โ”œโ”€โ”€ Multiple schema versions exist
   โ”œโ”€โ”€ Applications specify version
   โ””โ”€โ”€ Complex but allows gradual migration

   Example: v1_users, v2_users

3. Event Sourcing
   โ”œโ”€โ”€ Store events, not state
   โ”œโ”€โ”€ Replay to any schema version
   โ””โ”€โ”€ Most flexible, most complex

   Events: UserCreated, UserNameChanged, UserDeleted
   โ†’ Replay to construct current state

Migration Tools:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Tool        โ”‚ Language   โ”‚ Approach                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Flyway      โ”‚ Java/SQL   โ”‚ SQL migrations, versioned       โ”‚
โ”‚ Liquibase   โ”‚ Java/XML   โ”‚ Changelog format, rollback      โ”‚
โ”‚ Alembic     โ”‚ Python     โ”‚ SQLAlchemy integration          โ”‚
โ”‚ Entity Frameworkโ”‚ .NET   โ”‚ Code-first migrations           โ”‚
โ”‚ Prisma      โ”‚ TypeScript โ”‚ Declarative schema              โ”‚
โ”‚ Atlas       โ”‚ Go         โ”‚ Declarative + imperative        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Keys and Identifiers

Primary Key Strategies

Primary Key Options:

1. Natural Keys
   โ”œโ”€โ”€ Business identifier (email, SSN, ISBN)
   โ”œโ”€โ”€ Pros: Meaningful, unique in business
   โ”œโ”€โ”€ Cons: Can change, privacy concerns
   โ””โ”€โ”€ Use: When truly immutable

2. Surrogate Keys (Recommended)
   โ”œโ”€โ”€ Auto-increment integer
   โ”œโ”€โ”€ Pros: Simple, performant, stable
   โ”œโ”€โ”€ Cons: Meaningless, DB-specific
   โ””โ”€โ”€ Use: Most operational systems

3. UUIDs
   โ”œโ”€โ”€ Universally unique identifier
   โ”œโ”€โ”€ Pros: Globally unique, distributed generation
   โ”œโ”€โ”€ Cons: Larger, less performant
   โ””โ”€โ”€ Use: Distributed systems, external exposure

4. ULIDs / Snowflake IDs
   โ”œโ”€โ”€ Time-sortable unique identifiers
   โ”œโ”€โ”€ Pros: Sortable, unique, distributed
   โ”œโ”€โ”€ Cons: More complex generation
   โ””โ”€โ”€ Use: Time-series, event systems

Comparison:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Type          โ”‚ Size    โ”‚ Sortable โ”‚ Distributed โ”‚ Example โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Auto-incrementโ”‚ 4-8 bytesโ”‚ Yes     โ”‚ No          โ”‚ 12345   โ”‚
โ”‚ UUID v4       โ”‚ 16 bytesโ”‚ No       โ”‚ Yes         โ”‚ a1b2c...โ”‚
โ”‚ UUID v7       โ”‚ 16 bytesโ”‚ Yes      โ”‚ Yes         โ”‚ 0188... โ”‚
โ”‚ ULID          โ”‚ 16 bytesโ”‚ Yes      โ”‚ Yes         โ”‚ 01H5... โ”‚
โ”‚ Snowflake     โ”‚ 8 bytes โ”‚ Yes      โ”‚ Yes         โ”‚ 7890... โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Composite Keys

Composite Keys:
Primary keys with multiple columns.

Use Cases:
โ”œโ”€โ”€ Junction tables (many-to-many)
โ”œโ”€โ”€ Time-series with partitioning
โ”œโ”€โ”€ Multi-tenant systems
โ””โ”€โ”€ Natural business keys

Example: Order Items (SQL Server - PascalCase)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ OrderItems                                                   โ”‚
โ”‚ โ”œโ”€โ”€ OrderId     PK, FK                                      โ”‚
โ”‚ โ”œโ”€โ”€ LineNumber  PK       (composite with OrderId)           โ”‚
โ”‚ โ”œโ”€โ”€ ProductId   FK                                          โ”‚
โ”‚ โ”œโ”€โ”€ Quantity                                                โ”‚
โ”‚ โ””โ”€โ”€ Price                                                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Trade-offs:
โ”œโ”€โ”€ Pros: Enforces uniqueness, natural ordering
โ”œโ”€โ”€ Cons: Complex foreign keys, ORM challenges
โ””โ”€โ”€ Alternative: Surrogate key + unique constraint

Best Practices

Data Modeling Best Practices:

1. Understand the Use Case First
   โ”œโ”€โ”€ OLTP vs OLAP requirements
   โ”œโ”€โ”€ Query patterns expected
   โ”œโ”€โ”€ Write vs read ratio
   โ””โ”€โ”€ Growth expectations

2. Start Normalized, Denormalize with Reason
   โ”œโ”€โ”€ Begin with 3NF for operational
   โ”œโ”€โ”€ Denormalize only for proven performance needs
   โ”œโ”€โ”€ Document denormalization decisions
   โ””โ”€โ”€ Consider materialized views first

3. Use Consistent Naming (Database-Specific)
   โ”œโ”€โ”€ Singular table names (User, not Users)
   โ”œโ”€โ”€ SQL Server: PascalCase (CustomerId, OrderDate, CreatedAt)
   โ”œโ”€โ”€ PostgreSQL: snake_case (customer_id, order_date, created_at)
   โ”œโ”€โ”€ Foreign keys: {Entity}Id or {entity}_id per convention
   โ””โ”€โ”€ Avoid reserved words

4. Document Everything
   โ”œโ”€โ”€ Column descriptions
   โ”œโ”€โ”€ Relationship meanings
   โ”œโ”€โ”€ Business rules
   โ””โ”€โ”€ Change history

5. Plan for Change
   โ”œโ”€โ”€ Use surrogate keys
   โ”œโ”€โ”€ Design for schema evolution
   โ”œโ”€โ”€ Version your schemas
   โ””โ”€โ”€ Test migrations thoroughly

6. Consider Performance Early
   โ”œโ”€โ”€ Index strategy
   โ”œโ”€โ”€ Partitioning needs
   โ”œโ”€โ”€ Data types (smallest sufficient)
   โ””โ”€โ”€ Query patterns

Anti-Patterns

Data Modeling Anti-Patterns:

1. "One Table to Rule Them All"
   โŒ Single table with many nullable columns
   โœ“ Proper entity separation

2. "Entity-Attribute-Value (EAV)"
   โŒ Generic key-value tables
   โœ“ Proper columns or JSON fields

3. "CSV in a Column"
   โŒ Comma-separated values in one field
   โœ“ Proper junction table

4. "Premature Denormalization"
   โŒ Denormalize without measuring
   โœ“ Start normalized, optimize with data

5. "No Foreign Keys"
   โŒ Skipping FK for 'performance'
   โœ“ Use FK for integrity, consider indexes

6. "Meaningless Names"
   โŒ table1, field_a, temp_data
   โœ“ Descriptive, consistent naming

Related Skills

  • data-architecture - Data lake, lakehouse, data mesh
  • stream-processing - Real-time data modeling
  • database-scaling - Scaling data systems
  • etl-elt-patterns - Data transformation