How do you de-normalise?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction to De-Normalization
De-normalization is a database optimization technique used in the design of relational database systems where additional, redundant copies of data are added to enhance read performance of the database. While normalization eliminates redundancy and ensures data integrity, it can lead to complex query operations. De-normalization, on the other hand, simplifies query execution at the possible expense of updates and storage costs.
When to De-Normalize
Deciding whether to de-normalize requires careful consideration of various factors like read and write operations' frequency, complexity of queries, and system architecture. De-normalization is typically considered when:
- Queries require multiple table joins that become a performance bottleneck.
- The system experiences heavy read-operations compared to write operations.
- Reducing latency for read-heavy applications is critical.
Techniques of De-Normalization
- Duplicating Data: This involves duplicating necessary data fields in multiple tables to avoid joins.
- Storing Precomputed Values: Calculated columns (e.g., total sales price) are stored in a table instead of computing them during query time.
- Using Composite Key Tables: Aggregate information into a single lookup table to eliminate the need for multiple joins.
- Denormalizing Hierarchical Data: Store hierarchical relationships in a flattened structure rather than separate parent-child tables.
Example of De-Normalization
Consider a normalized e-commerce application with the following schema:
- Users Table: Stores user information.
- Orders Table: Stores order information with fields like user_id.
- Products Table: Stores product details.
- OrderItems Table: Relates orders to products.
A normalized query to obtain user information, order details, and product names for each order could look like:
- Add
user_nameandproduct_namefields directly in the OrderItems table. - Improved Read Performance: Simplifies queries and reduces the computational cost.
- Reduced Complexity: Fewer tables and joins can lead to simpler query structures.
- Faster Reporting: Better suited for data analytics and reporting tasks where read speed is critical.
- Increased Storage Costs: Redundancy and duplicated data consume more storage.
- Update Complexity: Multiple copies of data need to be updated concurrently, complicating the update operations.
- Risk of Inconsistency: Greater redundancy can lead to new types of inconsistencies.
- Balance between read and write efficiencies.
- Potential for data integrity challenges.
- The architectural cost of data redundancies.
- Long-term maintenance scalability.
Related reading
- How do you debug MySQL stored procedures?
- How do you do a limit query in JPQL or HQL?
- How do you effectively model inheritance in a database?
- How do you get the index of the current iteration of a foreach loop?
- How do you determine the ideal buffer size when using FileInputStream?
- How do you make TensorFlow Keras fast with a TFRecord dataset?
- How do you include postgresql.conf on docker container when using org.testcontainers
- How do you like your primary keys?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.