Skip to content

Denormalization

Intentionally introducing redundancy into a normalized database to improve read performance.

Normalization → remove redundancy → more tables → more JOINs. Denormalization → add redundancy back → fewer tables → fewer JOINs.

When to Denormalize

  • Read-heavy systems (90% reads, 10% writes)
  • JOINs are killing performance (query runs 10,000 times/second with 5 table JOINs)
  • Aggregations computed too often (COUNT(*) on every profile view)
  • Data warehouses / analytics (OLAP)

Common Denormalization Techniques

1. Storing Derived/Computed Data

sql
-- Instead of: SELECT COUNT(*) FROM likes WHERE post_id = 101
-- Store: Posts table with like_count column
-- Increment like_count on every like

2. Duplicating Columns Across Tables

sql
-- Normalized: Orders + Users → JOIN needed for user_name
-- Denormalized: Orders (order_id, user_id, user_name) → no JOIN

3. Pre-joining Tables (Flattening)

sql
-- OrderSummary: user_id, user_name, order_id, product_name, qty, price
-- Single table scan instead of 4-way JOIN

4. Storing Aggregates

sql
-- Users: (user_id, name, total_spent)
-- Update total_spent on every order → instant dashboard loads

When NOT to Denormalize

  • Write-heavy tables — every write must update redundant data
  • Frequently changing data — update one thing, must update many tables
  • Small tables / simple queries — JOINs are already fast
  • Strong consistency requirements (banking, financial)

Normalization vs Denormalization

NormalizedDenormalized
RedundancyNoneIntentional
Write speedFasterSlower
Read speedSlower (joins)Faster (no joins)
ConsistencyEasyHarder
Use caseOLTP, writesOLAP, reads
ExamplesBanking, ERPAnalytics, feeds

Rule: Never denormalize first. Always normalize then denormalize where needed based on measured performance.