In this lesson, you’ll learn how to break normalization rules by duplicating data across rows to eliminate expensive joins in read-heavy database architectures.
The Cost of Normalization
In traditional relational modeling, we normalize data to prevent anomalies—storing a user's address in one table and referencing it by user_id in an orders table. While this saves space and ensures consistency, it forces the database to perform a JOIN every time you display an order history. In a system serving millions of requests, these joins become a performance bottleneck.
Denormalization via Row Duplication
Denormalization is the strategic process of adding redundant data to a table to make read queries faster. Instead of joining tables, we "bake" the required information directly into the rows where it is frequently accessed.
For example, consider an e-commerce platform. Instead of looking up the username from a Users table for every Order, we store the username directly inside the Orders table:
-- Before: Normalized (Requires JOIN)
SELECT o.order_id, u.username
FROM Orders o
JOIN Users u ON o.user_id = u.id;
-- After: Denormalized
-- The 'username' is now stored locally in the Orders table
SELECT order_id, username
FROM Orders;
When to Denormalize
This strategy is highly effective when your application is read-heavy and the performance of SELECT statements is more critical than the storage overhead of duplicated data. However, remember that denormalization shifts the complexity from reads to writes.
If a user changes their username, you now face a consistency challenge: you must update the username field in both the Users table and every single row in the Orders table where that user appears. This can be handled by background workers or event-driven updates (much like the Pub-Sub patterns you’ve studied previously).
Because you are intentionally duplicating data, you must ensure your application logic accounts for potential desynchronization, perhaps by using eventual consistency models or batch reconciliation processes to ensure the "source of truth" remains valid.
Key Takeaway: Denormalization improves read performance by embedding frequently joined data directly into a table, trading off increased storage usage and complex write-path synchronization for significantly faster query execution.